Updated 2016-04-22 22:12:18 by gold

WJG (18/Mar/06) I'm sure that some of the more elaborate widget packages out there provide this sort of function but I just wanted something simple. Here, the scrolled listbox presents the user with a selection of alternatives, perhaps the result of a database search, click one of them and then do something with the result.
 # scrolledlistbox.tcl
 # by William J Giddings, 2006.
 # Description:
 # -----------
 # Display a scrolled list box, pick, then perform some follow up action.
 # Usage:
 # -----
 # See demo code below

 proc scrolledlistbox {w values cmd args} {
  frame $w
  eval listbox $w.list $args 
  $w.list configure -yscrollcommand "$w.scrl set"
  scrollbar $w.scrl -command "$w.list yview"
  pack $w.scrl -side right -fill y
  pack $w.list -side left -fill both -expand 1

  set j true
  set indx 0
  foreach i $values {
    $w.list insert end $i
    if {$j} {
      set j false
      $w.list itemconfigure $indx -background #ffffdd
    } else {
      set j true
    incr indx
  # bindings
  # this will obtain the item clicked, and then pass
  # the value onto the proc specified in the variable cmd. 

  eval "bind $w.list <ButtonRelease-1> \{$cmd \[\%\W get \@\%x,\%y\]\}"

  # return the widget path
  return $w 

 # demo stuff
 proc cmd {a} { puts ">>> $a" }

 console show
 set values {one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen}

 set aa {-}
 pack [scrolledlistbox .slb $values cmd -font {Arial 12} ] -fill both -expand 1

EG You can (should?) use format or list to avoid the quoting hell. The bind line then becomes:
  bind $w.list <ButtonRelease-1> [format {%s [%%W get @%%x,%%y]} $cmd]

  eval [list bind $w.list <ButtonRelease-1> "$cmd \[%W get @%x,%y\]"]

Take your pick, I personally prefer the first.

MG You can also bind to <<ListboxSelect>> instead of <ButtonRelease-1> to have your code run when the selection is changed, and use something like
  bind $w.list <<ListboxSelect>> [list $cmd %W]
  proc cmd {w} {puts "$w has [$w curselection]"}

Zipguy (2013-01-14) - Or you can deal with some real things, like files, for example by replacing the simple unstatic list with:
 set values [glob *.*]

for the list. :)

But changing directories is another matter entirely.

Zipguy 2013-07-15 - I got some time and wrote a program which does use this routine in it called Primitive Directory Browser