在网格中指定本地动态

我想用不同的方式动态更新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用在abc中的任何a ,而这些我不想在show变化时更新,它们的变化取决于其他触发器。 为什么不移除然后show第一行的符号? 想象一下,我不能,因为show存在于abc使用的功能中,而我无法轻松访问此功能。

当然,将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解决方案的评论,并提出了修复以避免手动分割第二行,但由于评论区域中的空间限制,我将其作为答案发布。 纳赛尔确认其有效并将其纳入他的答案后,会很乐意将其删除。

有关解决方案的线索可以在文档的ItemPossible 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