我想以不同的方式动态更新Grid
的特定部分。请考虑以下玩具示例:我有两行:一行必须逐个更新( a , b , c ),如下所示:这些符号取决于不同的触发器;第二行依赖于一个允许显示/隐藏某些数据的单个触发器( show )。
现在我知道我可以将整个Grid
结构包装到Dynamic
中,甚至可以指定要跟踪的符号,因此这个示例可以满足我的需求:
Checkbox[Dynamic[show]]
test = {0, 0};
Dynamic[Grid[{{Dynamic@a, Dynamic@b, Dynamic@c},
If[show, Prepend[test, "test:"], {}]}, Frame -> All],
TrackedSymbols :> {show}]
虽然出于某些原因我希望在本地指定Dynamic
,但这只适用于Grid
的第二行。
对于那些想知道什么是不道德的情况的人,想象一下:show
a
,b
或c
中的任何一个都会使用show
我不想在show
更改时更新,其更改取决于其他触发器。为什么不从第一行的符号中删除show
?想象一下,我不能,因为a
,b
或c
中使用的函数中存在If
,而且我无法轻松访问此函数。
当然,将Dynamic
的第一个参数包装到Grid
中对此没有帮助,因为Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
If[Dynamic@show, Prepend[test, "test:"], {}]
}, Frame -> All]
本身或其任何单元格都不会变为动态:
Dynamic
此外,将行换行到List
会使给定行无效,因为它不再有头Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
Dynamic@If[show, Prepend[test, "test:"], {}]
}, Frame -> All]
:
Dynamic
在行上映射show
不起作用,因为Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
Dynamic /@ If[show, Prepend[test, "test:"], {}]
}, Frame -> All]
未动态更新:
Dynamic[If[...]]
此外,将If
包裹在列表成员周围工作,但现在我必须评估Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
Dynamic[If[show, #, ""]] & /@ Prepend[test, "test:"]
}, Frame -> All]
3次而不是1次。
Dynamic
想知道是否有任何解决方案可以通过在行上本地应用{{1}}包装来克服此特定问题。
答案 0 :(得分:3)
以下是使用实验ValueFunction
show = True;
test = {0, 0};
Checkbox[Dynamic[show]]
现在在侧面编写自己的小动态更新功能
Needs["Experimental`"];
row = {};
updateRow[x_, v_] := row = If[v, Prepend[test, "test:"], {}];
ValueFunction[show] = updateRow;
现在制作网格,现在可以在每一行上使用Dynamic,而不是整个网格,这就是你想要的:
Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
{Dynamic@row}
},
Frame -> All
]
PS。我刚刚通过telefunkenvf14阅读了这篇文章,提到了这个包和这个函数,我不知道,当我看到这个函数时,我记得这个问题,我认为应该可以使用该函数来解决这个问题
PS。我需要更多地正确地放置网格行....
<强>更新(1)强>
我无法想象如何将最后一行拼接在网格中的列上。这很奇怪,因为它有List头,但它不会遍历所有列。它只会进入第一个细胞。尝试过序列,SpanFromLeft等,但没有运气。也许有人可以把这部分搞清楚。
这是我目前的试用版:
Needs["Experimental`"];
row = {};
updateRow[x_, v_] := row = If[v, {"test:", 0, 0}, {}];
ValueFunction[show] = updateRow;
show = False;
Checkbox[Dynamic[show]]
f = Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
List@Dynamic[row]
},
Frame -> All
]
它似乎应该是可行的。我现在看不出有什么问题......
<强>更新(2)强>
作为临时解决方案,我事先用力拆分第二排。这使我可以做我想做的事。不确定这是否符合OP规范(我的猜测是不符合),但这里是:
Needs["Experimental`"];
ra = 0;
rb = 0;
rc = 0;
updateRow[x_, v_] :=
row = If[v, ra = "test:"; rb = 0; rc = 0, ra = ""; rb = ""; rc = ""]
ValueFunction[show] = updateRow;
show = False;
Checkbox[Dynamic[show]]
f = Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
{Dynamic@ra, Dynamic@rb, Dynamic@rc}
},
Frame -> All]
答案 1 :(得分:1)
这实际上是对@ Nasser解决方案的评论,并建议修复以避免手动拆分第二行,但由于评论区域的空间限制,我将其作为答案发布。一旦纳赛尔确认它有效并将其纳入他的答案中,将很乐意将其删除。
解决方案的线索可在文档中Possible Issues
的{{1}}部分找到:
如果Item不是支持Item的函数的子项中最顶层的项,则它将不起作用。
我用以下方式修改@ Nasser的解决方案。首先,我需要更改Item
的定义,以便对row
的两个值show
的长度都相同。
row
需要进行的第二项更改是使用Needs["Experimental`"];
row = {"", "", ""};
updateRow[x_, v_] := row = If[v, Prepend[test, "test:"], {"", "", ""}];
Experimental`ValueFunction[show] = updateRow;
Dynamic@row
的每个元素
Item
编辑:Grid[{{Dynamic@a, Dynamic@b, Dynamic@c},
{Item[Dynamic@row[[1]]], Item[Dynamic@row[[2]]],
Item[Dynamic@row[[3]]]}}, Frame -> All]
包装器并不是真正需要的;它没有它也能正常工作:
Item