Occasionally it would be preferable to have some initialization code for palettes (of buttons). For example, it could define some functions that are used by palette buttons.
What is the easiest and preferable way to define/run initialization code for a palette?
CreatePalette
, etc.)You're right to be concerned about the visibility of the Dynamic
being an issue. The way to absolutely guarantee a Dynamic
expression to be evaluated regardless of the visibility of any of the individual cells is to use NotebookDynamicExpression
. Here's an example that illustrates NotebookDynamicExpression
working while a Dynamic
fails because it's hidden within a closed cell group:
cell1 = First @ MakeBoxes[
TextCell["Click to open", "Title",
CellMargins -> 0, System`WholeCellGroupOpener -> True],
StandardForm];
cell2 = First @ MakeBoxes[
ExpressionCell[DynamicWrapper["hidden cell", Print["DynamicWrapper"]]],
StandardForm];
CreatePalette[
Notebook[{Cell[CellGroupData[{cell1, cell2}, Closed]]},
NotebookDynamicExpression :>
Dynamic[Refresh[Print["NotebookDynamicExpression"], None]]]]
When you evaluate this, note that the Dynamic
in NotebookDynamicExpression
evaluates immediately. The DynamicWrapper
never evaluates until you open the cell group, which you can do by clicking on the "Click to open" text.
In this example, incidentally, notice that I wrapped the NotebookDynamicExpression
with Refresh
. The function Refresh[#, None]&
will make sure that the code evaluates only once -- when the notebook is first opened. Otherwise, the code would obey the standard properties of Dynamic
and evaluate whenever any of the dependencies change.
NotebookDynamicExpression
has been around since v6, but was only documented in v8. Also documented are its related cousins, CellDynamicExpression
and FrontEndDynamicExpression
.