This runtime coercion or type test from type 'a to Ellipse
-
Tuesday, April 03, 2012 9:56 AM
This runtime coercion or type test from type 'a to Ellipse
involves an indeterminate type based on information prior to this program point.
Runtime type tests are not allowed on some types. Further type annotations are needed.
open System open System.IO open System.Net open System.Net.Sockets open System.Text open System.Threading open System.Collections.Generic open System.Collections open Microsoft.FSharp.Collections open System.Drawing open System.Windows.Forms open System.Collections.Generic open System.Windows open System.Windows.Controls open System.Windows.Markup open System.Configuration open System.Data open System.Data.SqlClient open System.Configuration open System.Windows.Media open System.Windows.Media.Imaging open System.Collections.ObjectModel open System.Windows.Shapes open System.Runtime.Serialization open System.Runtime.Serialization.Formatters.Binary open System.Security.Cryptography open System.Linq open System.Reflection open System.Xml open System.Xml.Linq [<AttributeUsage(AttributeTargets.Field, AllowMultiple = false)>] type UiElementAttribute(name : string) = inherit System.Attribute() new() = new UiElementAttribute(null) member this.Name = name [<AbstractClass>]type FsUiObject<'T when 'T :> FrameworkElement> (xamlPath) as this = let loadXaml () = use stream = System.IO.File.OpenRead(xamlPath) System.Windows.Markup.XamlReader.Load(stream) let uiObj = loadXaml() :?> 'T let flags = System.Reflection.BindingFlags.Instance ||| System.Reflection.BindingFlags.NonPublic ||| System.Reflection.BindingFlags.Public do let fields = this.GetType().GetFields(flags) |> Seq.choose(fun f -> let attrs = f.GetCustomAttributes(typeof<UiElementAttribute>, false) if attrs.Length = 0 then None else let attr = attrs.[0] :?> UiElementAttribute Some(f, if String.IsNullOrEmpty(attr.Name) then f.Name else attr.Name) ) for field, name in fields do let value = uiObj.FindName(name) if value <> null then field.SetValue(this, value) else failwithf "Ui element %s not found" name member x.UiObject = uiObj let _random = new Random() let Damping = 0.95 let Gravity = 0.7; let Resistance = 0.995 let TotalBalls = 2 (* AY : double, AX : double, X : double, Y : double, OldX : double, OldY : double *) type PhysicsInfo() = member g.AY with get() = AY and set(value) = AY <- value member g.AX with get() = AX and set(value) = AX <- value member g.X with get() = X and set(value) = X <- value member g.Y with get() = Y and set(value) = Y <- value member g.OldX with get() = OldX and set(value) = OldX <- value member g.OldY with get() = OldY and set(value) = OldY <- value let InitPhysicsForBall : PhysicsInfo= let p = new PhysicsInfo() //_random.NextDouble() * ActualWidth, //_random.NextDouble() * ActualHeight, p.AY = _random.NextDouble() * 600.0 p.AX = _random.NextDouble() * 480.0 p.X = _random.NextDouble() * 10.0 p.Y =_random.NextDouble() * 10.0 p.OldX = 0.0, p.OldY = 0.0 //) p let CreateBalls(win : FsUiObject<Window>) = for i = 0 to TotalBalls-1 do let e : Ellipse = new Ellipse() e.Width <- 20.0 e.Height <- 20.0 let _container = win.UiObject.FindName("_container") :?> Canvas _container.Children.Add(e) let info = InitPhysicsForBall e.Tag <- info let SetConstraints(win : FsUiObject<Window>, ball : Ellipse, info : PhysicsInfo) = let _container = win.UiObject.FindName("_container") :?> Canvas let bounds : Size = _container.RenderSize if info.X <= 0.0 then info.X <- 0.0 info.AX <- info.AX * -1.0 * Damping else if info.X >= bounds.Width - ball.Width then info.X <- bounds.Width - ball.Width info.AX <- info.AX * (-1.0) * Damping if info.Y <= 0.0 then info.Y <- 0.0 info.AY <- info.AY*(-1.0) * Damping else if info.Y >= (bounds.Height - ball.Height) then info.Y <- bounds.Height - ball.Height info.AY <- info.AY*(-1.0) * Damping let UpdateBall(win : FsUiObject<Window>, info : PhysicsInfo) = info.AX = info.AX* Resistance info.AY = info.AY + Gravity info.AY = info.AY * Resistance info.X = info.X + info.AX info.Y = info.Y + info.AY let CompositionTarget_Rendering(win : FsUiObject<Window>) = let _container = win.UiObject.FindName("_container") :?> Canvas for i = 0 to TotalBalls-1 do let ball : Ellipse = _container.Children[i] :?> Ellipse <--- Error let info : PhysicsInfo = ball.Tag :?> PhysicsInfo UpdateBall(win, info) SetConstraints(win, ball, info) ball.SetValue(Canvas.LeftProperty, info.X) ball.SetValue(Canvas.TopProperty, info.Y) let Window1_Loaded(win : FsUiObject<Window>) = CreateBalls CompositionTarget.Rendering += CompositionTarget_Rendering(win); type MainWindow() as this = inherit FsUiObject<Window>(Path.Combine(__SOURCE_DIRECTORY__, "Window.xaml")) [<System.STAThread()>] do let window = new MainWindow() window.UiObject.Loaded += Window1_Loaded(window) window.UiObject.ShowDialog() |> ignore- Edited by 沈世鈞 Tuesday, April 03, 2012 9:57 AM
All Replies
-
Tuesday, April 03, 2012 12:38 PMSorry, it's really hard to parse huge listings. But if compiler cannot infer some type here then the easiest way is to add a type annotation for the type in question
Petr
-
Tuesday, April 03, 2012 8:05 PMModerator
_container.Children[i] :?> Ellipse
should be
_container.Children.[i] :?> Ellipse
array indexing in F# needs a dot
Brian McNamara [MSFT]
- Marked As Answer by 沈世鈞 Thursday, April 05, 2012 2:07 AM

