[AntdUI] 13 Panel控件的创建

nanyi 17小时前 51 v 1.0.0.0 2026-07-06

 import win.ui;
import dotNet.AntdUI;
import dotNet;

dotNet.import("System.Net");
dotNet.import("System.Drawing");
dotNet.import("System.Windows.Forms");
/*DSG{{*/
var winform = win.form(text="AntdUI Panel";right=920;bottom=660;bgcolor=0xF5F7FA)
winform.add(
host={cls="custom";left=20;top=20;right=900;bottom=640;db=1;dl=1;dr=1;dt=1;z=1}
)
/*}}*/

// ==========================================================
// 说明:
// 1. 本示例参考 https://ant.design/components/overview-cn/ 的组件总览卡片。
// ==========================================================

// ---------- 颜色 ----------
var rootBack = 0xFFF5F7FA;
var cardBack = 0xFFFFFFFF;
var cardHoverBack = 0xFFF7FAFF;
var cardBorder = 0xFFE8E8E8;
var cardHoverBorder = 0xFF1677FF;
var titleColor = 0xFF222222;
var titleHoverColor = 0xFF1677FF;
var splitColor = 0xFFE8E8E8;
var splitDrawingColor = System.Drawing.Color.FromArgb(232,232,232);

// ---------- 字体 ----------
var fontTitle = System.Drawing.Font("Microsoft YaHei",10,System.Drawing.FontStyle.Bold);
var fontHeader = System.Drawing.Font("Microsoft YaHei",12,System.Drawing.FontStyle.Bold);

// ---------- 根容器 ----------
var root = AntdUI.Panel(winform.host);
root.Dock = System.Windows.Forms.DockStyle.Fill;
root.Back = rootBack;
root.BackColor = rootBack;
root.Radius = 0;
root.BorderWidth = 0;


// 标题区域:用 FlowPanel 让 header 和 tag 自动横向排列
var headerFlow = AntdUI.FlowPanel();
root.Controls.Add(headerFlow);
headerFlow.Location = System.Drawing.Point(10,10);
headerFlow.Size = System.Drawing.Size(820,36);
headerFlow.BackColor = rootBack;
headerFlow.Gap = 6;
headerFlow.Padding = System.Windows.Forms.Padding(0,0,0,0);

// 标题
var header = AntdUI.Label();
header.Text = "AntdUI";
header.Font = fontHeader;
header.ForeColor = titleColor;
header.BackColor = rootBack;
header.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
header.AutoSize = true;

// 标题后面的数量 Tag
var headerTag = AntdUI.Tag();
headerTag.Size = System.Drawing.Size(40,24);
headerTag.Text = "12";
headerTag.Type = AntdUI.TTypeMini.Default;
headerTag.Font = System.Drawing.Font("Microsoft YaHei UI",9,System.Drawing.FontStyle.Regular);
headerTag.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;

headerFlow.Controls.Add(headerTag);
headerFlow.Controls.Add(header);

// 自动排列卡片的面板
var flow = AntdUI.FlowPanel();
root.Controls.Add(flow);
flow.Location = System.Drawing.Point(0,48);
flow.Size = System.Drawing.Size(860,560);
flow.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
flow.BackColor = rootBack;
flow.AutoScroll = true;
flow.Gap = 18;
flow.Padding = System.Windows.Forms.Padding(8,8,8,8);
flow.Align = AntdUI.TAlignFlow.Left

// ---------- SVG 下载与缓存 ----------
var svgCache = {};

// AntdUI.ImageSvg 更适合接收以 <svg ...> 开始的 SVG 片段。
// ant.design 的原始资源常带 XML 声明 / title,这里统一去掉。
var normalizeSvg = function(svg){
    svg = string.replace(svg,`^\s*\<\?xml[^\>]*\>\s*`,"");
    svg = string.replace(svg,`\<title\>.*?\</title\>\s*`,"");
    return svg;
}

var getSvg = function(url){
    if(svgCache[url]) return svgCache[url];

    var wc = System.Net.WebClient();
    wc.Encoding = System.Text.Encoding.UTF8;
    var svg = normalizeSvg(wc.DownloadString(url));
    wc.Dispose();

    svgCache[url] = svg;
    return svg;
}

// ---------- 鼠标是否仍在控件矩形内 ----------
var isMouseInControl = function(ctrl){
    var pt = ctrl.PointToClient(System.Windows.Forms.Control.MousePosition);
    return pt.X >= 0 && pt.Y >= 0 && pt.X < ctrl.Width && pt.Y < ctrl.Height;
}

// ---------- 卡片状态 ----------
var setCardState = function(cardObj,hover){
    var bg = hover ? cardHoverBack : cardBack;
    cardObj.card.BorderColor = hover ? cardHoverBorder : cardBorder;
    cardObj.title.ForeColor = hover ? titleHoverColor : titleColor;
    cardObj.card.Invalidate();
    cardObj.title.Invalidate();
    cardObj.divider.Invalidate();
    cardObj.imageBox.Invalidate();
}

var bindCardHover = function(cardObj,ctrl){
    ctrl.MouseEnter = function(sender,e){
        setCardState(cardObj,true);
    }

    ctrl.MouseLeave = function(sender,e){
        // 鼠标从 Panel 移到内部 Label / Divider / Avatar 时,父控件可能触发 MouseLeave。
        // 延迟一下再判断鼠标是否仍在整个 card 区域内,避免 hover 状态闪烁。
        thread.delay(1);
        if(!isMouseInControl(cardObj.card)){
            setCardState(cardObj,false);
        }
    }
}

// ---------- 创建卡片 ----------
var createCard = function(item){
    var card = AntdUI.Panel();
    flow.Controls.Add(card);

    card.Size = System.Drawing.Size(300,300);
    card.Radius = 8;
    card.BorderWidth = 1;
    card.BorderColor = cardBorder;

    // Panel.Back 是实际填充色;BackColor 使用父背景色,可避免圆角外侧白角。
    card.Back = cardBack;
    card.BackColor = rootBack;

    card.Shadow = 0;
    card.ShadowOffsetY = 4;
    card.ShadowColor = System.Drawing.Color.FromArgb(255,0,0,0);
    card.ShadowOpacity = 0.10;
    card.ShadowOpacityHover = 0.22;
    card.ShadowOpacityAnimation = true;
    card.Cursor = System.Windows.Forms.Cursors.Hand;

    // 顶部标签,左对齐。
    var title = AntdUI.Label();
    card.Controls.Add(title);
    title.Location = System.Drawing.Point(32,16);
    title.Size = System.Drawing.Size(240,34);
    title.Text = item.name ++ "  " ++ item.cn;
    title.Font = fontTitle;
    title.ForeColor = titleColor;
    title.BackColor = cardBack;
    title.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
    title.AutoEllipsis = true;
    title.Cursor = System.Windows.Forms.Cursors.Hand;

    // 标题下方分割线。使用 WinForms Panel 做 1px 线,更接近网页卡片。
    var divider = System.Windows.Forms.Panel();
    card.Controls.Add(divider);
    divider.Location = System.Drawing.Point(16,58);
    divider.Size = System.Drawing.Size(268,1);
    divider.BackColor = splitDrawingColor;
    divider.Cursor = System.Windows.Forms.Cursors.Hand;

    // SVG 展示区。Avatar 原生支持 ImageSvg,不需要手动转换 Bitmap。
    var imageBox = AntdUI.Avatar();
    card.Controls.Add(imageBox);
    imageBox.Location = System.Drawing.Point(60,92);
    imageBox.Size = System.Drawing.Size(180,160);
    imageBox.BackColor = cardBack;
    imageBox.Radius = 0;
    imageBox.Round = false;
    imageBox.ImageFit = AntdUI.TFit.Contain;
    imageBox.ImageSvg = getSvg(item.url);
    imageBox.Cursor = System.Windows.Forms.Cursors.Hand;

    var cardObj = {
        card = card;
        title = title;
        divider = divider;
        imageBox = imageBox;
    }

    bindCardHover(cardObj,card);
    bindCardHover(cardObj,title);
    bindCardHover(cardObj,divider);
    bindCardHover(cardObj,imageBox);

   var clickHandler = function(sender,e){
    	AntdUI.Message.info(
        	AntdUI.Target(card),
        	"已点击:" ++ item.name ++ " / " ++ item.cn,
        	fontTitle,
        	3
    	);
	}

    card.Click = clickHandler;
    title.Click = clickHandler;
    divider.Click = clickHandler;
    imageBox.Click = clickHandler;

    return cardObj;
}

// ---------- 官方组件图 URL,来自 ant.design/components/overview-cn ----------
var items = [
    {name="Button";cn="按钮";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*7va7RKs3YzIAAAAAAAAAAAAADrJ8AQ/original"},
    {name="FloatButton";cn="悬浮按钮";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*tXAoQqyr-ioAAAAAAAAAAAAADrJ8AQ/original"},
    {name="Icon";cn="图标";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*PdAYS7anRpoAAAAAAAAAAAAADrJ8AQ/original"},
    {name="Typography";cn="排版";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*MLt3R6m9huoAAAAAAAAAAAAADrJ8AQ/original"},
    {name="Divider";cn="分割线";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*7sMiTbzvaDoAAAAAAAAAAAAADrJ8AQ/original"},
    {name="Flex";cn="弹性布局";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*SMzgSJZE_AwAAAAAAAAAAAAADrJ8AQ/original"},
    {name="Grid";cn="栅格";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*mfJeS6cqZrEAAAAAAAAAAAAADrJ8AQ/original"},
    {name="Layout";cn="布局";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*4i58ToAcxaYAAAAAAAAAAAAADrJ8AQ/original"},
    {name="Space";cn="间距";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*ZiJ3SbOH9SUAAAAAAAAAAAAADrJ8AQ/original"},
    {name="Tabs";cn="标签页";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*72NDQqXkyOEAAAAAAAAAAAAADrJ8AQ/original"},
    {name="Table";cn="表格";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*3yz3QqMlShYAAAAAAAAAAAAADrJ8AQ/original"},
    {name="Form";cn="表单";url="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*-lcdS5Qm1bsAAAAAAAAAAAAADrJ8AQ/original"}
];

// ---------- 批量创建 ----------
flow.SuspendLayout();
for(i,item in items){
    createCard(item);
}
flow.ResumeLayout(true);

winform.onClose = function(){
    fontTitle.Dispose();
    fontHeader.Dispose();
}

winform.show();
win.loopMessage();

最新回复 (2)
  • ccbwx 6小时前
    0 2
    漂亮
  • lcj21 4小时前
    0 3
    好看,感谢分享!
返回