我有兩個建議:
1)如果您使用F#交互檢查已安裝了世界糧食計劃署的事件循環。 F#交互默認情況下設置了winforms eventloop,在winforms和WFP事件循環之間有一些兼容性,但並非所有工作都能正確執行。要安裝事件循環使用下面的腳本:
#light
// When running inside fsi, this will install a WPF event loop
#if INTERACTIVE
#I "c:/Program Files/Reference Assemblies/Microsoft/Framework/v3.0";;
#I "C:/WINDOWS/Microsoft.NET/Framework/v3.0/WPF/";;
#r "presentationcore.dll";;
#r "presentationframework.dll";;
#r "WindowsBase.dll";;
module WPFEventLoop =
open System
open System.Windows
open System.Windows.Threading
open Microsoft.FSharp.Compiler.Interactive
open Microsoft.FSharp.Compiler.Interactive.Settings
type RunDelegate<'b> = delegate of unit -> 'b
let Create() =
let app =
try
// Ensure the current application exists. This may fail, if it already does.
let app = new Application() in
// Create a dummy window to act as the main window for the application.
// Because we're in FSI we never want to clean this up.
new Window() |> ignore;
app
with :? InvalidOperationException -> Application.Current
let disp = app.Dispatcher
let restart = ref false
{ new IEventLoop with
member x.Run() =
app.Run() |> ignore
!restart
member x.Invoke(f) =
try disp.Invoke(DispatcherPriority.Send,new RunDelegate<_>(fun() -> box(f()))) |> unbox
with e -> eprintf "\n\n ERROR: %O\n" e; rethrow()
member x.ScheduleRestart() = ()
//restart := true;
//app.Shutdown()
}
let Install() = fsi.EventLoop <- Create()
WPFEventLoop.Install();;
#endif
2)我沒有測試過這太清楚,但我想用一個動畫故事板會給濃煙更一致的結果,而不是使用一個計時器。我認爲這將看起來像(改變寬度屬性還沒有計算出如何改變位置):
#light
open System
open System.Windows
open System.Windows.Controls
open System.Windows.Shapes
open System.Windows.Media
open System.Windows.Media.Animation
let rect = new Rectangle(Fill = new SolidColorBrush(Colors.Red), Height = 20., Width = 20., Name = "myRectangle")
let canvas =
let c = new Canvas()
c.Children.Add(rect) |> ignore
c
NameScope.SetNameScope(canvas, new NameScope());
canvas.RegisterName(rect.Name, rect)
let window = new Window(Content = canvas)
let nfloat f = new Nullable<float>(f)
let myDoubleAnimation = new DoubleAnimation(From = nfloat 20.0, To = nfloat 50.0,
Duration = new Duration(TimeSpan.FromSeconds(5.)),
RepeatBehavior = RepeatBehavior.Forever)
let myStoryboard =
let sb = new Storyboard()
sb.Children.Add(myDoubleAnimation)
sb
Storyboard.SetTargetName(myDoubleAnimation, rect.Name);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.WidthProperty))
rect.Loaded.Add(fun _ -> myStoryboard.Begin canvas)
let main() =
let app = new Application()
app.Run window |> ignore
[<STAThread>]
do main()
感謝您的建議。因爲你說這可能是F#交互式的問題,我在C#中做了同樣的例子。 C#代碼也沒有工作。我的問題是每個tick的0.01移動太低。我認爲1.0將是整個窗口,所以0.01將是窗口的1%。 – Jules 2008-12-26 10:53:58