Your problem doesn't require the use of Dynamic. In fact, you may have noticed that dynamicstr is highlighted in red inside Dynamic[dynamicstr] because it's not quite correct to use Block or Module with Dynamic; DynamicModule is recommended instead.
If I remove the Dynamic from your code and add some extra Print statements, I get the following:
dynamicTest[] := Block[{dynamicstr, i}, Print["current value: ", dynamicstr]; For[i = 1, i <= 10, i++, dynamicstr = ToString[i];Print[dynamicstr]; ]; dynamicstr = "Done";Print[dynamicstr]; ]; dynamicTest[] current value: dynamicstr
1
2
3
4
5
6
7
8
9
10
Done
(I also removed the Pause.)
Running it a second time:
dynamicTest[] current value: dynamicstr 1 2 3 4 5 6 7 8 9 10 Done Using Module instead of Block makes no difference.
dynamicTest2[] := Module[{dynamicstr, i}, Print["current value: ", dynamicstr]; For[i = 1, i <= 10, i++, dynamicstr = ToString[i];Print[dynamicstr]; ]; dynamicstr = "Done";Print[dynamicstr]; ]; dynamicTest2[] current value: dynamicstr$29032 1 2 3 4 5 6 7 8 9 10 Done dynamicTest2[] current value: dynamicstr$29035 1 2 3 4 5 6 7 8 9 10 Done To get the behavior you want, you'll need to move your variable outside of any scoping construct and make it global:. Scoping constructs localize their variables lexically or dynamically, to prevent retaining values set by code inside across calls.
dynamicstr; dynamicTest3[] := Block[{i}, Print["current value: ", dynamicstr]; For[i = 1, i <= 10, i++, dynamicstr = ToString[i];Print[dynamicstr]; ]; dynamicstr = "Done";Print[dynamicstr]; ]; dynamicTest3[] current value: dynamicstr 1 2 3 4 5 6 7 8 9 10 Done dynamicTest3[] current value: Done 1 2 3 4 5 6 7 8 9 10 Done Notice that for the second run, the variable is still set to "Done" from the first pass.