👾 修复 Select 鼠标滚轮 DividerSelectItem 选中、Table 复选支持int 0,1、DatePicker/Select/TimePicker 新增 ExpandDropChanged、修复 Mask 隐藏后依旧显示

This commit is contained in:
Tom
2025-11-10 17:16:16 +08:00
parent 37a3f3bb9c
commit 495c7d9108
19 changed files with 237 additions and 80 deletions

View File

@@ -7,6 +7,7 @@
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<ForceDesignerDpiUnaware>true</ForceDesignerDpiUnaware>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<ItemGroup>

View File

@@ -1,14 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<ForceDesignerDpiUnaware>true</ForceDesignerDpiUnaware>
<ApplicationIcon>icon.ico</ApplicationIcon>
<ForceDesignerDpiUnaware>true</ForceDesignerDpiUnaware>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<WindowsSupportedOSPlatformVersion>5.1</WindowsSupportedOSPlatformVersion>
<TargetPlatformMinVersion>5.1</TargetPlatformMinVersion>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
@@ -27,11 +28,14 @@
<ItemGroup>
<PackageReference Include="PublishAotCompressed" Version="1.0.5" />
<PackageReference Include="VC-LTL" Version="5.2.2" />
<PackageReference Include="WinFormsComInterop" Version="0.5.0" />
<PackageReference Include="YY-Thunks" Version="1.1.7" />
<RdXmlFile Include="rd.xml" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'net10.0-windows'">
<PackageReference Include="WinFormsComInterop" Version="0.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\AntdUI\AntdUI.csproj" />
<ProjectReference Include="..\..\src\AntdUI.EmojiFluentFlat\AntdUI.EmojiFluentFlat.csproj" />

View File

@@ -31,7 +31,9 @@ namespace Demo
[STAThread]
static void Main(string[] arge)
{
#if !NET10_0
ComWrappers.RegisterForMarshalling(WinFormsComInterop.WinFormsComWrappers.Instance);
#endif
var command = string.Join(" ", arge);
AntdUI.Localization.DefaultLanguage = "zh-CN";
var lang = AntdUI.Localization.CurrentLanguage;

View File

@@ -7,6 +7,7 @@
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<ForceDesignerDpiUnaware>true</ForceDesignerDpiUnaware>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<ItemGroup>

View File

@@ -7,6 +7,7 @@
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<ForceDesignerDpiUnaware>true</ForceDesignerDpiUnaware>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFrameworks>net9.0-windows;net8.0-windows;net6.0-windows;net48;net46;net40</TargetFrameworks>
<TargetFrameworks>net10.0-windows;net9.0-windows;net8.0-windows;net6.0-windows;net48;net46;net40</TargetFrameworks>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<Authors>Tom</Authors>
@@ -27,7 +27,7 @@
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net40' OR '$(TargetFramework)'=='net46' OR '$(TargetFramework)'=='net48'">
<ItemGroup Condition="'$(TargetFramework)' == 'net40' OR '$(TargetFramework)' == 'net46' OR '$(TargetFramework)' == 'net48'">
<Reference Include="System.Design" />
</ItemGroup>

View File

@@ -197,6 +197,14 @@ namespace AntdUI
[Description("预置点击时发生"), Category("行为")]
public event ObjectNEventHandler? PresetsClickChanged;
/// <summary>
/// 下拉展开 属性值更改时发生
/// </summary>
[Description("下拉展开 属性值更改时发生"), Category("行为")]
public event BoolEventHandler? ExpandDropChanged;
protected virtual void OnExpandDropChanged(bool e) => ExpandDropChanged?.Invoke(this, new BoolEventArgs(e));
#endregion
#region
@@ -235,6 +243,7 @@ namespace AntdUI
}
}
else subForm?.IClose();
OnExpandDropChanged(value);
}
}

View File

@@ -303,6 +303,14 @@ namespace AntdUI
[Description("预置点击时发生"), Category("行为")]
public event ObjectNEventHandler? PresetsClickChanged;
/// <summary>
/// 下拉展开 属性值更改时发生
/// </summary>
[Description("下拉展开 属性值更改时发生"), Category("行为")]
public event BoolEventHandler? ExpandDropChanged;
protected virtual void OnExpandDropChanged(bool e) => ExpandDropChanged?.Invoke(this, new BoolEventArgs(e));
#endregion
#region
@@ -357,6 +365,7 @@ namespace AntdUI
}
}
else subForm?.IClose();
OnExpandDropChanged(value);
}
}

View File

@@ -154,6 +154,8 @@ namespace AntdUI
if (container is GridPanel parent && parent.IsHandleCreated)
{
if (parent.PauseLayout) return false;
var point = parent.PointToScreen(Point.Empty);
if (point.X == point.Y && point.X < 0 && point.Y < 0) return false;
var rect = parent.DisplayRectangle;
if (!string.IsNullOrEmpty(Span) && parent.Controls.Count > 0)
{

View File

@@ -422,17 +422,20 @@ namespace AntdUI
{
var g = e.Canvas;
var rect_read = ReadRectangle;
float _radius = radius * Config.Dpi;
using (var path = DrawShadow(g, _radius, e.Rect, rect_read))
if (rect_read.Width > 0 && rect_read.Height > 0)
{
using (var brush = backExtend.BrushEx(rect_read, back ?? Colour.BgContainer.Get(nameof(Panel), ColorScheme)))
float _radius = radius * Config.Dpi;
using (var path = DrawShadow(g, _radius, e.Rect, rect_read))
{
g.Fill(brush, path);
using (var brush = backExtend.BrushEx(rect_read, back ?? Colour.BgContainer.Get(nameof(Panel), ColorScheme)))
{
g.Fill(brush, path);
}
if (backImage != null) g.Image(rect_read, backImage, backFit, _radius, false);
if (borderWidth > 0) g.Draw(borderColor ?? Colour.BorderColor.Get(nameof(Panel), ColorScheme), borderWidth * Config.Dpi, borderStyle, path);
}
if (backImage != null) g.Image(rect_read, backImage, backFit, _radius, false);
if (borderWidth > 0) g.Draw(borderColor ?? Colour.BorderColor.Get(nameof(Panel), ColorScheme), borderWidth * Config.Dpi, borderStyle, path);
if (ArrowAlign != TAlign.None) g.FillPolygon(back ?? Colour.BgContainer.Get(nameof(Panel), ColorScheme), ArrowAlign.AlignLines(ArrowSize, e.Rect, rect_read));
}
if (ArrowAlign != TAlign.None) g.FillPolygon(back ?? Colour.BgContainer.Get(nameof(Panel), ColorScheme), ArrowAlign.AlignLines(ArrowSize, e.Rect, rect_read));
base.OnDraw(e);
}

View File

@@ -346,6 +346,14 @@ namespace AntdUI
protected virtual void OnSelectedValueChanged(object? e) => SelectedValueChanged?.Invoke(this, new ObjectNEventArgs(e));
/// <summary>
/// 下拉展开 属性值更改时发生
/// </summary>
[Description("下拉展开 属性值更改时发生"), Category("行为")]
public event BoolEventHandler? ExpandDropChanged;
protected virtual void OnExpandDropChanged(bool e) => ExpandDropChanged?.Invoke(this, new BoolEventArgs(e));
/// <summary>
/// 关闭某项 时发生
/// </summary>
@@ -540,6 +548,7 @@ namespace AntdUI
subForm = null;
filtertext = "";
}
OnExpandDropChanged(value);
}
}
@@ -621,13 +630,43 @@ namespace AntdUI
{
base.OnMouseWheel(e);
if (ReadOnly || !WheelModifyEnabled || items == null || items.Count == 0) return;
int newIndex;
if (e.Delta > 0) newIndex = SelectedIndex <= 0 ? items.Count - 1 : SelectedIndex - 1;
else newIndex = SelectedIndex >= items.Count - 1 ? 0 : SelectedIndex + 1;
SelectedIndex = newIndex;
SelectedIndex = IMouseWheel(items, e.Delta);
if (e is HandledMouseEventArgs handled) handled.Handled = true;
}
int IMouseWheel(BaseCollection items, int delta)
{
int count = items.Count, errcount = 0, newIndex;
if (delta > 0)
{
newIndex = SelectedIndex <= 0 ? items.Count - 1 : SelectedIndex - 1;
while (WheelItem(items[newIndex]))
{
errcount++;
if (errcount > count) return -1;
newIndex--;
if (newIndex < 0) newIndex = count - 1;
}
}
else
{
newIndex = SelectedIndex >= items.Count - 1 ? 0 : SelectedIndex + 1;
while (WheelItem(items[newIndex]))
{
errcount++;
if (errcount > count) return -1;
newIndex++;
if (newIndex > count - 1) newIndex = 0;
}
}
return newIndex;
}
bool WheelItem(object? it)
{
if (it is DividerSelectItem) return true;
return false;
}
#endregion
#region

View File

@@ -673,6 +673,18 @@ namespace AntdUI
#endregion
#region
/// <summary>
/// 下拉展开 属性值更改时发生
/// </summary>
[Description("下拉展开 属性值更改时发生"), Category("行为")]
public event BoolEventHandler? ExpandDropChanged;
protected virtual void OnExpandDropChanged(bool e) => ExpandDropChanged?.Invoke(this, new BoolEventArgs(e));
#endregion
#region
bool expandDrop = false;
@@ -714,6 +726,7 @@ namespace AntdUI
subForm?.IClose();
filtertext = "";
}
OnExpandDropChanged(value);
}
}

View File

@@ -999,24 +999,39 @@ namespace AntdUI
{
//复选框
has_check = true;
bool value_check = false;
bool value_check = false, val_int = false;
if (value is bool check) value_check = check;
return new TCellCheck(this, columnCheck, prop, ov, value_check);
else if (value is int check_int)
{
value_check = check_int > 0;
val_int = true;
}
return new TCellCheck(this, columnCheck, prop, ov, value_check, val_int);
}
else if (column is ColumnRadio columnRadio)
{
//单选框
has_check = true;
bool value_check = false;
bool value_check = false, val_int = false;
if (value is bool check) value_check = check;
return new TCellRadio(this, columnRadio, prop, ov, value_check);
else if (value is int check_int)
{
value_check = check_int > 0;
val_int = true;
}
return new TCellRadio(this, columnRadio, prop, ov, value_check, val_int);
}
else if (column is ColumnSwitch columnSwitch)
{
//开关
bool value_check = false;
bool value_check = false, val_int = false;
if (value is bool check) value_check = check;
return new TCellSwitch(this, columnSwitch, prop, ov, value_check);
else if (value is int check_int)
{
value_check = check_int > 0;
val_int = true;
}
return new TCellSwitch(this, columnSwitch, prop, ov, value_check, val_int);
}
else if (column is ColumnSelect columnSelect)
{
@@ -1360,6 +1375,13 @@ namespace AntdUI
if (count > 0 && nocount == count) columnCheck.Checked = value;
}
void SetValueCheck(CELL_CHECK cel) => SetValueCheck(cel, !cel.Checked);
void SetValueCheck(CELL_CHECK cel, bool value)
{
cel.Checked = value;
if (cel.ValInt) SetValue(cel, value ? 1 : 0);
else SetValue(cel, value);
}
void SetValue(CELL cel, object? value)
{
if (cel.PROPERTY == null)

View File

@@ -373,15 +373,13 @@ namespace AntdUI
var value = columnCheck.Call(!checkCell.Checked, it.row.RECORD, it.i_row, it.i_cel);
if (checkCell.Checked != value)
{
checkCell.Checked = value;
SetValue(it.cell, checkCell.Checked);
SetValueCheck(checkCell, value);
OnCheckedChanged(checkCell.Checked, it.row.RECORD, it.i_row, it.i_cel, db.col);
}
}
else if (checkCell.AutoCheck)
{
checkCell.Checked = !checkCell.Checked;
SetValue(it.cell, checkCell.Checked);
SetValueCheck(checkCell);
OnCheckedChanged(checkCell.Checked, it.row.RECORD, it.i_row, it.i_cel, db.col);
}
}
@@ -404,15 +402,10 @@ namespace AntdUI
if (i != it.i_row)
{
var cell_selno = rows[i].cells[it.i_cel];
if (cell_selno is TCellRadio radioCell2 && radioCell2.Checked)
{
radioCell2.Checked = false;
SetValue(cell_selno, false);
}
if (cell_selno is TCellRadio radioCell2 && radioCell2.Checked) SetValueCheck(radioCell2, false);
}
}
radioCell.Checked = true;
SetValue(it.cell, radioCell.Checked);
SetValueCheck(radioCell, true);
OnCheckedChanged(radioCell.Checked, it.row.RECORD, it.i_row, it.i_cel, db.col);
}
}
@@ -428,17 +421,12 @@ namespace AntdUI
{
var value = columnSwitch.Call(!switchCell.Checked, it.row.RECORD, it.i_row, it.i_cel);
if (switchCell.Checked == value) return;
switchCell.Checked = value;
SetValue(it.cell, value);
}).ContinueWith(action =>
{
switchCell.Loading = false;
});
SetValueCheck(switchCell, value);
}).ContinueWith(action => switchCell.Loading = false);
}
else if (switchCell.AutoCheck)
{
switchCell.Checked = !switchCell.Checked;
SetValue(it.cell, switchCell.Checked);
SetValueCheck(switchCell);
OnCheckedChanged(switchCell.Checked, it.row.RECORD, it.i_row, it.i_cel, db.col);
}
}

View File

@@ -239,7 +239,7 @@ namespace AntdUI
/// <summary>
/// 复选框
/// </summary>
class TCellCheck : CELL
class TCellCheck : CELL_CHECK
{
/// <summary>
/// 复选框
@@ -249,7 +249,7 @@ namespace AntdUI
/// <param name="prop">反射</param>
/// <param name="ov">行数据</param>
/// <param name="value">值</param>
public TCellCheck(Table table, ColumnCheck column, PropertyDescriptor? prop, object? ov, bool value) : base(table, column, prop, ov)
public TCellCheck(Table table, ColumnCheck column, PropertyDescriptor? prop, object? ov, bool value, bool valint) : base(table, column, prop, ov, valint)
{
_checked = value;
AnimationCheckValue = _checked ? 1F : 0F;
@@ -268,7 +268,7 @@ namespace AntdUI
bool _checked = false;
[Description("选中状态"), Category("行为"), DefaultValue(false)]
public bool Checked
public override bool Checked
{
get => _checked;
set
@@ -327,7 +327,6 @@ namespace AntdUI
#endregion
public bool NoTitle { get; set; }
public bool AutoCheck { get; set; }
#endregion
@@ -411,7 +410,7 @@ namespace AntdUI
/// <summary>
/// 单选框
/// </summary>
class TCellRadio : CELL
class TCellRadio : CELL_CHECK
{
/// <summary>
/// 单选框
@@ -421,7 +420,7 @@ namespace AntdUI
/// <param name="prop">反射</param>
/// <param name="ov">行数据</param>
/// <param name="value">值</param>
public TCellRadio(Table table, ColumnRadio column, PropertyDescriptor? prop, object? ov, bool value) : base(table, column, prop, ov)
public TCellRadio(Table table, ColumnRadio column, PropertyDescriptor? prop, object? ov, bool value, bool valint) : base(table, column, prop, ov, valint)
{
_checked = value;
AnimationCheckValue = _checked ? 1F : 0F;
@@ -439,7 +438,7 @@ namespace AntdUI
bool _checked = false;
[Description("选中状态"), Category("行为"), DefaultValue(false)]
public bool Checked
public override bool Checked
{
get => _checked;
set
@@ -497,8 +496,6 @@ namespace AntdUI
#endregion
public bool AutoCheck { get; set; }
#endregion
#region
@@ -573,7 +570,7 @@ namespace AntdUI
/// <summary>
/// 开关
/// </summary>
class TCellSwitch : CELL
class TCellSwitch : CELL_CHECK
{
/// <summary>
/// 开关
@@ -583,7 +580,7 @@ namespace AntdUI
/// <param name="prop">反射</param>
/// <param name="ov">行数据</param>
/// <param name="value">值</param>
public TCellSwitch(Table table, ColumnSwitch column, PropertyDescriptor? prop, object? ov, bool value) : base(table, column, prop, ov)
public TCellSwitch(Table table, ColumnSwitch column, PropertyDescriptor? prop, object? ov, bool value, bool valint) : base(table, column, prop, ov, valint)
{
_checked = value;
AnimationCheckValue = _checked ? 1F : 0F;
@@ -601,7 +598,7 @@ namespace AntdUI
bool _checked = false;
[Description("选中状态"), Category("行为"), DefaultValue(false)]
public bool Checked
public override bool Checked
{
get => _checked;
set
@@ -757,8 +754,6 @@ namespace AntdUI
#endregion
public bool AutoCheck { get; set; }
#endregion
#region
@@ -845,6 +840,18 @@ namespace AntdUI
public override string ToString() => Checked.ToString();
}
abstract class CELL_CHECK : CELL
{
public CELL_CHECK(Table table, Column column, PropertyDescriptor? prop, object? ov, bool val_int) : base(table, column, prop, ov)
{
ValInt = val_int;
}
public abstract bool Checked { get; set; }
public bool AutoCheck { get; set; }
public bool ValInt { get; set; }
}
/// <summary>
/// 拖拽手柄
/// </summary>

View File

@@ -1636,21 +1636,9 @@ namespace AntdUI
action_add = item =>
{
item.PARENT = it;
bool top = it.Controls.Count == 0;
item.Dock = DockStyle.Fill;
if (it.InvokeRequired)
{
it.Invoke(() =>
{
it.Controls.Add(item);
if (top) item.Showed = true;
});
}
else
{
it.Controls.Add(item);
if (top) item.Showed = true;
}
if (it.InvokeRequired) it.Invoke(() => it.Controls.Add(item));
else it.Controls.Add(item);
};
action_del = (item, index) =>
{
@@ -1867,11 +1855,13 @@ namespace AntdUI
#region
bool showed = false;
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("显示的"), Category("外观"), DefaultValue(false)]
public bool Showed
{
get => showed;
set
internal set
{
if (showed == value) return;
showed = value;

View File

@@ -134,6 +134,14 @@ namespace AntdUI
protected virtual void OnValueChanged(TimeSpan e) => ValueChanged?.Invoke(this, new TimeSpanNEventArgs(e));
/// <summary>
/// 下拉展开 属性值更改时发生
/// </summary>
[Description("下拉展开 属性值更改时发生"), Category("行为")]
public event BoolEventHandler? ExpandDropChanged;
protected virtual void OnExpandDropChanged(bool e) => ExpandDropChanged?.Invoke(this, new BoolEventArgs(e));
#endregion
#region
@@ -172,6 +180,7 @@ namespace AntdUI
}
}
else subForm?.IClose();
OnExpandDropChanged(value);
}
}

View File

@@ -73,6 +73,7 @@ namespace AntdUI
public override string name => "Mask";
Func<GraphicsPath>? RenderRegion;
Control[]? list;
protected override void OnLoad(EventArgs e)
{
if (control == null)
@@ -91,24 +92,32 @@ namespace AntdUI
Size = owner.Size;
Location = owner.Location;
}
owner.VisibleChanged += Parent_VisibleChanged;
}
else
{
if (control is TabPage page) page.ShowedChanged += Parent_VisibleChanged;
control.VisibleChanged += Parent_VisibleChanged;
var point = control.PointToScreen(Point.Empty);
SetLocation(point);
SetSize(control.Size);
Size = control.Size;
Location = point;
var tmps = control.FindPARENTs();
list = tmps.ToArray();
foreach (var control in list)
{
if (control is TabPage page) page.ShowedChanged += Parent_VisibleChanged;
control.VisibleChanged += Parent_VisibleChanged;
control.Disposed += Parent_Disposed;
}
}
owner.VisibleChanged += Parent_VisibleChanged;
owner.LocationChanged += Parent_LocationChanged;
owner.SizeChanged += Parent_SizeChanged;
LoadVisible();
base.OnLoad(e);
}
private void Parent_Disposed(object? sender, EventArgs e) => IClose();
private void Parent_VisibleChanged(object? sender, EventArgs e) => LoadVisible();
private void Parent_LocationChanged(object? sender, EventArgs e)
{
@@ -177,20 +186,32 @@ namespace AntdUI
}
bool GetVisible()
{
if (control == null) return owner.Visible;
if (list == null) return owner.Visible;
else
{
if (control is TabPage page) return page.Showed && page.Visible;
return control.Visible;
foreach (var control in list)
{
if (control is TabPage page)
{
if (!page.Showed) return false;
}
else if (!control.Visible) return false;
}
return true;
}
}
protected override void Dispose(bool disposing)
{
if (control != null)
if (list == null) owner.VisibleChanged -= Parent_VisibleChanged;
else
{
control.VisibleChanged -= Parent_VisibleChanged;
if (control is TabPage page) page.ShowedChanged -= Parent_VisibleChanged;
foreach (var control in list)
{
control.Disposed -= Parent_Disposed;
control.VisibleChanged -= Parent_VisibleChanged;
if (control is TabPage page) page.ShowedChanged -= Parent_VisibleChanged;
}
}
owner.LocationChanged -= Parent_LocationChanged;
owner.SizeChanged -= Parent_SizeChanged;

View File

@@ -101,6 +101,42 @@ namespace AntdUI
else if (target.Value is Control control) return FindPARENT(control.Parent, mdi);
return null;
}
public static List<Control> FindPARENTs(this Control control, bool mdi = false)
{
var list = new List<Control>(2);
if (control is DoubleBufferForm formd)
{
list.Add(formd);
if (formd.Tag is Form form)
{
list.Add(form);
return list;
}
else if (formd.Parent != null)
{
var tmp = FindPARENTs(formd.Parent, mdi);
if (tmp != null) list.AddRange(tmp);
return list;
}
else return list;
}
else if (control is Form form)
{
if (mdi) list.Add(form);
else list.Add(form.ParentForm ?? form);
return list;
}
else if (control.Parent != null)
{
list.Add(control);
var tmp = FindPARENTs(control.Parent, mdi);
if (tmp != null) list.AddRange(tmp);
}
else list.Add(control);
return list;
}
public static bool SetTopMost(this Control? control, IntPtr hand)
{
var form = control.FindPARENT();