在网格中指定本地动态
我想用不同的方式动态更新Grid
特定部分。 考虑下面的玩具示例:我有两行:一个必须逐一更新(a,b,c),因为这些符号取决于不同的触发器; 第二行取决于一个触发器(显示),它允许显示/隐藏一些数据。
现在我知道我可以将整个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
中的任何a
,而这些我不想在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
3倍,而不是1。
Grid[{
{Dynamic@a, Dynamic@b, Dynamic@c},
Dynamic[If[show, #, ""]] & /@ Prepend[test, "test:"]
}, Frame -> All]
想知道是否有任何解决方案通过在一行上局部应用Dynamic
包装来克服此特定问题。
这是一个使用实验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上使用,这正是您想要的:
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]
这实际上是对@ Nasser解决方案的评论,并提出了修复以避免手动分割第二行,但由于评论区域中的空间限制,我将其作为答案发布。 纳赛尔确认其有效并将其纳入他的答案后,会很乐意将其删除。
有关解决方案的线索可以在文档的Item
的Possible Issues
部分找到:
如果Item不是支持Item的函数的子项中的最顶层项目,它将不起作用。
我用以下方式修改@ Nasser的解决方案。 首先,我需要更改row
的定义,以便两个值的show
row
的长度相同。
Needs["Experimental`"];
row = {"", "", ""};
updateRow[x_, v_] := row = If[v, Prepend[test, "test:"], {"", "", ""}];
Experimental`ValueFunction[show] = updateRow;
第二个需要改变的是用Item
包装Dynamic@row
每个元素:
Grid[{{Dynamic@a, Dynamic@b, Dynamic@c},
{Item[Dynamic@row[[1]]], Item[Dynamic@row[[2]]],
Item[Dynamic@row[[3]]]}}, Frame -> All]
编辑: Item
包装不是真的需要; 没有它就可以工作:
Grid[{{Dynamic@a, Dynamic@b, Dynamic@c},
{Dynamic@row[[1]], Dynamic@row[[2]],
Dynamic@row[[3]]}}, Frame -> All]
链接地址: http://www.djcxy.com/p/57183.html
上一篇: Specify local Dynamic in Grid
下一篇: VS2010 Intellisense disabling itself randomly, ReSharper installed