如何在gridx的cell中显示控件?

C#游戏开发实战:从零构建坦克大战,掌握面向对象与游戏循环 游戏开发的核心在于理解游戏循环、对象管理与实时交互的逻辑架构。游戏循环驱动着每一帧的状态更新与画面渲染,是游戏动态运行的基础。面向对象编程(OOP)则为游戏世界中的实体(如坦克、子弹、地图元素)提供了清晰、可扩展的建模方式,通过封装、继承与多态组织复杂逻辑。在2D游戏开发中,碰撞检测是确保交互真实性的关键技术,它决定了物体间的物理接触与反应。将这些技术应用于实践,能高效构建逻辑驱动的经典游戏。本文以C#和WinForms/GDI+为工具,深入剖析如何实现一个包含完整AI、碰撞系统与关卡编辑的坦克大战复刻版, 阅读详情

在gridx的列定义中,一个decorator方法可以被用来在cell中显示任何HTML/CSS. 但是有时候这稍显不够。当cell中需要放入复杂的控件时,从decorator方法中返回的纯string不再有效。所以gridx/modules/CellWidget模块在这是显示了作用。



为何是CellWidget


CellWidget模块通过grid的body模块中的onAfterRow事件将widget附加到cell节点中。其中的关键是如何才能高效地完成这个工作。

Grid的body随着时间不断刷新,刷新的原因可以是排序,过滤,分页,虚拟滚动,改变值,展开树节点,等等。每次body被刷新,行被重新,并且onAfterRow事件将会被处罚。如果我们总是在onAfterRow事件中创建新的widget,那将会非常浪费。如果你点击header两次为了要是的一列降序排序,许多widget将会被立刻摧毁。所以一些缓存机制必须被建立。第一个方法是为在每个cell中使用一个widget,无论被刷新多少次。这解决了一些刷新问题,但是如果我们有100000行,这仍然不高效。试想如果一个用户慢慢地滚动这个巨大的grid来看每一行,最终将会有多少widget被创建!

所以CellWidget的目的是创建尽可能少的控件。方法是使用set('value',...)方法在row之间重用控件。


如何使用CellWidget


在控件上设置值通常比创建一个新控件快。这是一个好方法,但是需要用户意识到重用这件事情。让我们首先看一下如何使用CellWidget模块:

var grid = new Grid({
    cacheClass: 'gridx/core/model/cache/Async',
    store: someStore,
    structure: [
        { id: 'progress', field: 'progress', name: 'Install Progress',
            widgetsInCell: true,
            decorator: function(){
                return "<div data-dojo-type='dijit.ProgressBar' data-dojo-props='maximum: 1' " + 
                    "class='gridxHasGridCellValue' style='width: 100%;'></div>";
            }
        }
    ],
    modules: [
        "gridx/modules/CellWidget"
    ]
});

  • 首先,不要忘记载入所有必要的资源: store, cache, 模块和你想要在cell中展示的widget。如果你仍然在创建一个gridx的时候遇到麻烦,请阅读这篇教程.
  • 第二,在你想要显示widgets的列中将widgetsInCell 属性设置为true。CellWidget模块将只会在这些列上有效。
  • 第三,在你的设置widgetsInCell的列中提供decorator 方法。


从decorator方法中返回模板字符串


这里你将看到第一个小技巧:decorator并没有任何的参数。这并不是当widgetsInCell 为false的情况。通常当前的cell数据会被传入,和row Id和Index一起。如果某些特定的cell数据被传入,我们将如何重用他们?所以这个template string不能包含任何特定的行信息。在上面的示例中,一个dijit/ProgressBar被放进template中,他的参数可以在data-dojo-props中被加入。注意这个gridxhasGridCellValue class,这是关于widgets被重用的第二个技巧。CellWidget模块将会在渲染每一行时自动查找所有含有这个class的widget,并且调用set('value')在widget中设置合适的值。


在setCellValue中设置widgets


在上面的例子中,在调用 widget的 set('value')之前不需要转换数据,因此事情显得比较简单。在设置widget值的时候,如果你想做一些有趣的事情,该怎么办? setCellValue方法在这个时候派上了用处。

{ id: 'progress', field: 'progress', name: 'Install Progress',
    widgetsInCell: true,
    decorator: function(){
        return "<div data-dojo-type='dijit.ProgressBar' data-dojo-props='maximum: 1' " +
            "data-dojo-attach-point='progBar' style='width: 100%;'></div>";
    },
    setCellValue: function(gridData, storeData, cellWidget){
        var data = doSomethingIntersting(gridData);
        cellWidget.progBar.set('value', data);
        // cellWidget.cell give you full access to everything you want.
        var rowIndex = cellWidget.cell.row.index();
    }
}

setCellValue方法会在每一行被render的时候被调用。当这个方法被调用时,widget已经被创建并且你能完全控制widget。你可以在widgets上设置值,改变css,或者操纵dom节点并且添加事件。这个方法中的第三个参数'cellWidget'引用了cell widget本身,这是拥有从'decorater'方法中返回的template string的widget,所以你可以访问任何的在控件中定义的“dojo attach point”。第一和第二个参数是当前cell的grid data与store data。他们只有当'formatter'方法被提供时才会有差别。你可以通过cellWidget.cell来获取当前的cell,从中你可以获取任何你需要的东西。


如何处理widget事件

但是请记住widgets("cell widget"作为一个整体)是在不同的行之间被重用。所以如果你在setCellValue方法中绑定了一些事件或者改变了一些dom节点的时候,这些改变将会在被其他行重用时被保留。如果你一直连接事件而不断开事件,将会有巨大的内存泄漏风险。所以合适的方法是在setCellValue中连接并且断开事件。例如


{ id: 'progress', field: 'progress', name: 'Install Progress',
    widgetsInCell: true,
    decorator: function(){
        return "<button data-dojo-type='dijit.form.Button' data-dojo-attach-point='btn'></button>";
    },
    setCellValue: function(gridData, storeData, cellWidget){
        cellWidget.btn.set('label', gridData);
        if(cellWidget.btn._cnnt){
            // Remove previously connected events to avoid memory leak.
            cellWidget.btn._cnnt.remove();
        }
        cellWidget.btn._cnnt = dojo.connect(cellWidget.btn, 'onClick', function(e){
            alert(gridData);
            // do your job here......
        });
    }
}

我承认,这看起来不怎么直观。所以在gridx 1.2中一个新的方法(回调)在会被引入以使得这个工作更加简便:

{ id: 'progress', field: 'progress', name: 'Install Progress',
    widgetsInCell: true,
    decorator: function(){
        return "<button data-dojo-type='dijit.form.Button' data-dojo-attach-point='btn'></button>";
    },
    setCellValue: function(gridData, storeData, cellWidget){
        cellWidget.btn.set('label', gridData);
    },
    getCellWidgetConnects: function(cellWidget, cell){
        // return an array of connection arguments
        return [
            [cellWidget.btn, 'onClick', function(e){
                alert(cell.data());
                // do your job here.....
            }]
        ];
    }
}

有了这个getCellWidgetConnects,gridx可以为你管理事件链接(句柄)。连接和断开都会被自动执行。


其他高级的回调函数

初次之外,gridx 1.2添加了另外2个方法来为你的工作提供更加有意义的命名:

{ id: 'progress', field: 'progress', name: 'Install Progress',
    widgetsInCell: true,
    decorator: function(){
        return "<button data-dojo-type='dijit.form.Button' data-dojo-attach-point='btn'></button>";
    },
    setCellValue: function(gridData, storeData, cellWidget){
        cellWidget.btn.set('label', gridData);
    },
    getCellWidgetConnects: function(cellWidget, cell){
        // return an array of connection arguments
        return [
            [cellWidget.btn, 'onClick', function(e){
                alert(cell.data());
                // do your job here.....
            }]
        ];
    },
    initializeCellWidget: function(cellWidget, cell){
        // create extra widgets or manipulate dom nodes that depends on current cell context.
        cellWidget.anotherButton = new Button({...});
        cellWidget.domNode.append(cellWidget.anotherButton.domNode);
    },
    uninitializeCellWidget: function(cellWidget, cell){
        // don't forget to undo the changes you made in initializeCellWidget, so that it can be reused among different rows.
        cellWidget.anotherButton.destroy();
    }
}

如你所见,事实上你可以在setCellValue方法中做这些事情。这个新方法只是提供了更多的语义,使你的代码更加易于阅读并且省去了你添加额外的注释的功夫。

创建控件的编程方式


如果你曾经用过DataGrid,你可能会对于在formatter方法中返回widget的方式感到熟悉,并且对于写template string的方式感到变扭。因此你可以使用onCellWidgetCreated事件,甚至省略“decorator”方法(gridx 1.2之后):

{ id: 'progress', field: 'progress', name: 'Install Progress',
    widgetsInCell: true,
    onCellWidgetCreated: function(cellWidget, column){
        var btn = new Button({...});
        btn.placeAt(cellWidget.domNode);
    }
}

onCellWidgetCreated 只当一个新的cell widget被创建时被调用。它不会在widget重用时被调用。跟decorator方法相同,不应该在此处使用特定行的信息。

结论

以下是如何在gridx的cell中显示widget的结论:

  1. 为grid引入gridx/moduels/CellWidget模块
  2. 在列设置中将widgetsInCell设置为true
  3. 在decorator方法中返回模板string,或者在onCellWidgetCreated事件处理函数中创建控件,或者两者皆执行
  4. 在setCellValue方法中设置widget的值(可选)
  5. 在getCellWidgetConnects中提供事件连接(可选,gridx 1.2之后)
  6. 在initialCellWidget和UninitialCellWidget中做额外的操作(可选,gridx 1.2之后)




安卓连连看游戏开发实战:从MVC架构到连通算法详解 在移动应用开发领域,游戏开发是综合运用UI设计、事件处理与核心算法的典型场景。其原理在于通过合理的架构模式(如MVC)分离数据、视图与控制逻辑,并依赖高效的算法(如连通性判断)处理游戏规则。这种实践对于理解软件工程的分层思想和算法应用具有重要价值,尤其在益智类游戏开发中,它直接决定了游戏的流畅度与可玩性。本文聚焦于一个经典的安卓《连连看》游戏项目,深入剖析了其**数据模型构建**与**连通性判断算法**的实现细节,为开发者提供了一个从零构建完整应用、融合技术理论与工程实践的绝佳范例。 阅读详情

相关推荐

GridCellCheck表格控件

GridCellCheck表格控件

关于oracle触发器before和after的应用问题

详细整理了oracle中before和after的使用问题

最强大的布局方案——网格Grid布局万字详解

最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。移动端浏览器:*) 从上图我们可以看出第一列的宽度为150px,第二列和第三列以1:2的比例均分了剩余空间) 如上图所示,第三列的宽度最小不小于10px,最大不超过50px。

郊眠寺 1万+

dojo dgrid cell生成简化单元格

将dojo之dgrid开源复杂表格控件进行改造。dgrid表格的body cell初始化结构与header cell一样,仅通过css很难较好的展示多级header+单级body的表格情况,因此进行了改造。 另外,还针对columnsset结构做了一定扩展,允许为td设置className,并将该样式和field一并追加到默认样式之后,可通过此配置实现单列或某单元格样式的调整。

JavaScript装饰器函数(Decorator)实例详解

主要介绍了JavaScript装饰器函数(Decorator),结合实例形式分析了JavaScript装饰器函数(Decorator)的功能、实现与使用方法,需要的朋友可以参考下

Robot Operating System——栅格单元(grid cells)

nav_msgs::msg::GridCells 是 ROS 2 中的一个消息类型,用于表示一组栅格单元(grid cells)。每个栅格单元表示一个二维平面上的点,通常用于表示占据栅格地图中的占据状态或路径规划中的路径点。它包含一个 std_msgs::msg::Header 和一个 std::vector,分别表示消息头和栅格单元的集合。GridCells 在机器人导航、路径规划、环境建模等场景中非常有用。

方亮的专栏 1638

Axure RP 10表单数据提交制作

本文介绍了如何使用Axure RP 10实现表单数据提交。

Peppaaa的博客 990

Gridx 显示控件故障一例

Gridx显示控件代码 HTML     Widget in Grid Cell Test                   .gridx {             width: 1000px;             height: 420px;         }                          Script脚本

Pipi0714的专栏 1001

Mumax3代码模板:从基础设置到材料参数优化

本文提供了一份详尽的Mumax3微磁学模拟代码模板,从基础网格设置、边界条件到核心材料参数(如钴的Msat、Aex、Ku1)配置与优化均有涵盖。文章深入解析了特征长度计算、初始化方法、弛豫与动力学模拟流程,并分享了并行计算与参数扫描等效率提升技巧,旨在帮助用户快速上手并优化模拟工作流。

moss5的博客 702

从安装到跑通第一个例程:Halcon 20.11深度学习版环境搭建全记录

本文详细记录了Halcon 20.11深度学习版环境搭建的全过程,从安装配置到运行第一个例程,特别针对CUDA版本冲突、算子验证和样本数据预处理等常见问题提供解决方案。通过实战案例展示PCB缺陷分类流程,帮助工程师快速掌握工业级图像处理技术,提升深度学习模型在工业质检中的应用效率。

weixin_28739079的博客 221

dojo dgrid 的列显示html控件

var columns = [ { field: "first", label: "First Name", formatter:function(data,ob...

weixin_33698043的博客 90

Ghidra逆向工具入门:从安装到实战分析baby.exe(附详细配置截图)

本文详细介绍了Ghidra逆向工具的安装配置与实战应用,通过破解CTF题目baby.exe的全过程展示其强大功能。从Java环境搭建到插件配置,再到反编译技巧与动态调试方法,帮助读者快速掌握这款免费开源的反编译神器,有效替代收费的IDA Pro工具。

weixin_29252171的博客 352

C++与EasyX实战:从零构建图形化扫雷游戏

在C++编程学习中,掌握核心数据结构与算法是基础,而图形界面开发则是将逻辑可视化的关键实践。二维数组作为存储网格数据的经典结构,递归算法常用于处理相邻元素的遍历与状态更新,这两者是实现游戏核心逻辑的基石。通过EasyX这一轻量级图形库,开发者可以绕过复杂的底层API,快速实现鼠标交互与图形绘制,将抽象的数据模型转化为直观的视觉界面。这种技术组合的价值在于,它能将枯燥的语法练习转化为一个完整的、可交互的工程项目,极大地提升学习动力与工程实践能力。其应用场景广泛,不仅是扫雷游戏,也适用于任何需要网格管理、状态模

weixin_33724659的博客 379

[Windows] 发票识别工具。支持xml、pdf、ofd文件。

发票识别是财务自动化中的关键环节,支持多种格式(XML、PDF、OFD)的识别工具能显著提升工作效率。以下介绍基于Windows平台开发此类工具的技术方案。发票识别是财务自动化中的关键环节,支持多种格式(XML、PDF、OFD)的识别工具能显著提升工作效率。以下介绍基于Windows平台开发此类工具的技术方案。

pZC_dqux的博客 667

YOLO11实战 第010期-基于yolo11的农业杂草作物目标检测实战文档(详细教程)

通过这条曲线,用户可以评估模型的检测能力,分析模型在不同阈值下对真实目标的检测是否全面。通过这条曲线,可以评估模型在目标检测任务中的整体性能,并找到合适的置信度阈值,以在精确率和召回率之间做出最佳平衡。PR 曲线越接近右上角,模型性能越好,曲线下方的面积越大,说明模型在不同置信度下的。),它展示了不同置信度下的召回率。条曲线都显示了随着召回率的增加,精确度略有下降的趋势,但整体上精确度保持在很高的水平。通过这条曲线,可以选择合适的置信度阈值,以优化模型的检测结果,平衡精确率和召回率。反映了分类器的准确性。

深度学习算法工程师,专注于前沿算法研究与实战应用。在这里,我将分享深度学习领域的实战经验、优质数据集资源以及最新论文解读与精度分析,旨在与广大技术爱好者共同探索人工智能的奥秘,助力技术成长与创新。 1522

C#俄罗斯方块游戏开发:从核心逻辑到图形界面的完整实现

面向对象编程和事件驱动模型是构建交互式应用程序的基础。在桌面应用开发中,通过分层架构实现关注点分离,能显著提升代码的可维护性和可测试性。这种设计模式的技术价值在于实现了高内聚、低耦合,使得核心业务逻辑可以独立于用户界面进行开发和测试。在游戏开发领域,俄罗斯方块作为一个经典练手项目,完美融合了游戏逻辑设计、实时状态管理和图形绘制等关键技术。本文以C#和Windows Forms为例,深入剖析了如何将核心游戏逻辑封装在独立的类库中,并详细讲解了包括7-Bag算法、双缓冲绘制和踢墙机制在内的关键实现细节,为开发者

weixin_33910460的博客 439

STLink驱动故障全解析:从卡顿到重装的终极修复指南

本文全面解析STLink驱动故障的常见现象及解决方案,包括驱动卸载、重装、Keil环境配置等关键步骤。针对设备管理器黄色感叹号、Keil识别异常等问题,提供从软件到硬件的终极修复指南,帮助开发者高效解决STLink连接问题。

sss66的博客 734

C#实现俄罗斯方块:从数据结构到游戏循环的完整实践指南

面向对象编程(OOP)是构建复杂软件系统的核心范式,它将数据和操作封装成对象,通过类、继承和多态等机制提升代码的可维护性和复用性。在游戏开发领域,这一原理尤为关键,游戏中的实体(如角色、物品)通常被建模为对象,其状态和行为通过类来定义。俄罗斯方块作为一个经典的编程实践项目,完美地融合了数据结构(如二维数组表示游戏区域)、事件驱动(处理键盘输入)和实时循环(控制方块下落)等核心技术。通过实现碰撞检测、方块旋转和消行逻辑,开发者能够深入理解游戏引擎的基本架构与状态管理。对于C#开发者而言,利用WinForms或

weixin_33755557的博客 350

YOLOv12改进策略【Neck】| 使用CARAFE轻量级通用上采样算子

CARAFE内容感知的特征重新组合。

Limiiiing的博客 664

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Unity热力图资源包:从数据可视化到性能优化的完整实现指南

数据可视化是游戏开发和数据分析中的基础技术,它通过图形化手段将抽象数据转化为直观的视觉信息,帮助开发者洞察数据分布与模式。其核心原理在于将离散数据点通过密度计算与插值算法(如高斯核密度估计)转化为连续的色彩分布,从而揭示数据的热点区域与趋势。在技术实现上,高效的网格化处理、GPU加速计算与着色器渲染构成了关键技术栈,这直接决定了可视化效果的流畅度与实时性。对于Unity开发者而言,一个封装完善的热力图资源包能够大幅降低技术门槛,将数据映射、颜色梯度配置、交互功能等复杂流程简化为可配置组件,其价值在于提升开发

cuml0912的博客 435

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

推箱子游戏:C#、C++、Java多语言项目实战与架构设计

游戏开发是理解编程核心概念的绝佳实践,其中状态机、碰撞检测和游戏循环是基础技术。状态机用于管理游戏对象的行为转换,碰撞检测确保对象交互的物理正确性,而游戏循环则是驱动每一帧逻辑与渲染的核心机制。这些技术共同支撑起游戏的实时性与交互性,在各类2D游戏、模拟仿真及交互应用中广泛应用。本文以经典的推箱子游戏为例,深入探讨如何运用数据驱动设计来构建游戏世界模型,并通过事件驱动与显式游戏循环等不同编程范式,在C#、C++和Java中实现高效的游戏逻辑与用户界面。项目实践将帮助你掌握从控制台到图形界面的完整开发流程,是

weixin_34405354的博客 376

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

CSS Grid 入门:二维布局时代的降维打击

CSS Grid 的出现,标志着前端工程师终于拥有了真正意义上为“二维布局”而生的原生工具。它不仅大幅减少了 CSS 代码量,更重要的是,它将布局逻辑从繁琐的样式计算中解放出来,提升到了架构设计的高度。

feixing_fx的博客 223

CSS网格布局Grid

CSS Grid 是一种强大的二维布局系统,能够以行和列的方式精确控制网页布局。它比传统的布局方式(如浮动、定位)更灵活、更强大,适合构建复杂的响应式网页。当项目超出定义的网格范围时,浏览器会自动创建隐式网格。(行间距 20px,列间距 30px)。(最小 100px,最大 1fr)。是线性布局的终极解决方案,擅长处理。是二维布局的革命性工具,擅长构建。(重复 3 列,每列宽度相等)。:定义行和列之间的间距(替代。(行和列间距均为 10px)。(从第 1 列到第 3 列)。:所有项目的水平对齐方式(

2301_82023822的博客 4954

神经网络与深度学习第五周总结

LSTM通过遗忘门来选择性地删除细胞状态中的一些信息,通过输入门来选择性地添加新的信息到细胞状态中,通过输出门来选择性地输出细胞状态中的一些信息到隐藏状态中。这样,LSTM可以有效地解决RNN存在的遗忘问题,即随着输入序列的增加,RNN会忘记之前的重要信息。这三种类型的区别在于反卷积部分的跳级结构,即在上采样的过程中,是否使用卷积部分的中间层的特征图进行求和运算。输出是一个 7×7×30的张量。这是因为RNN只有一个隐藏状态,用于存储和传递所有的信息,而这个隐藏状态的容量是有限的,不能无限地累积信息。

m0_50923478的博客 255

CSS进阶之grid网格布局 (三):关于grid布局、grid-container属性、grid-items属性

css网格布局擅长于将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系(前提是 HTML 生成了这些区域)。像表格一样,网格布局让我们能够按行或列来对齐元素。然而在布局上,网格比表格更可能做到或更简单。例如,网格容器的子元素可以自己定位,以便它们像 CSS 定位的元素一样,真正的有重叠和层次。1. 将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局;2. Grid 布局与 Flex 布局有一定的相似性,都可以指定容器内部多个项目的位置。但是,它们也存在重大区别。

Good Good Study,Day Day Up! 4098
上一篇: 如何使用 Gridx
下一篇: dojo-amd-converter工具包简介
dojotoolkit
博客等级 码龄16年 1205粉丝 61原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值