One of my blog reader asked why I inline XAML instead of putting it into a separate file and hooking up the variables manually in F#. My answer was laziness: I did not spend the time to figure out how. (If you subscribe to Larry Wall’s philosophy, laziness is a virtue …) Well, that question prompted me to look into how to externalize the xaml file and load it in. This dovetailed nicely with recipe 2.14 of the book Silverlight 2 Recipes, which shows how to load embedded resources. I put the xaml code in a separate file called page.xaml and added the following compiler flag:
--resource page.xaml
Here’s the xaml file:
<Canvas
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="LayoutRoot" Background="White">
<TextBlock>Hi There Reader</TextBlock>
<TextBlock Canvas.Left="20" Canvas.Top="20">Hi There</TextBlock>
<TextBlock Canvas.Left="40"
Canvas.Top="40">Silverlight</TextBlock>
<TextBlock Canvas.Left="60" Canvas.Top="60">
Silverlight</TextBlock>
<TextBlock Canvas.Left="80" Canvas.Top="80">
Silverlight</TextBlock>
<TextBlock Canvas.Left="100" Canvas.Top="100">
Silverlight</TextBlock>
</Canvas>
Here's the code that loads the xaml file and hook the control with a variable:
#light
namespace SilverLightFSharp
open System
open System.Resources
open System.Reflection
open System.IO
open System.Windows
open System.Windows.Browser
open System.Windows.Controls
open System.Windows.Markup
open List
// Recipe 2-14 and XAML from Recipe 3-3 of the Silverlight 2 Recipes book
type MyPage() = class
inherit UserControl()
do
let assembly = Assembly.GetExecutingAssembly();
let sr = new StreamReader(assembly.GetManifestResourceStream("page.xaml"));
let xamlControls = sr.ReadToEnd()
// Load xaml dynamically
let canvas = XamlReader.Load(xamlControls) :?> Canvas
base.Width <- 400.0
base.Height <- 300.0
base.Content <- canvas
end
type ErrorPage = class
inherit UserControl
new (msg:string ) as this = {} then
let textarea = new TextBlock(Text=msg,
TextWrapping=TextWrapping.Wrap,
Margin=new Thickness(4.0,4.0,4.0,4.0))
let sp = new StackPanel(HorizontalAlignment = HorizontalAlignment.Stretch,
Margin=new Thickness(8.0,8.0,10.0,8.0))
sp.Children.Add(textarea)
base.Width <- 600.0
base.Height <- 1000.0
base.Content <- sp
end
type MyApp = class
inherit Application
new () as this = {} then
this.Startup.Add(fun _ ->
let rootPanel = new StackPanel()
try
this.RootVisual <- rootPanel
rootPanel.Children.Add(new MyPage())
with _ as e ->
let msg = e.Message + e.StackTrace
rootPanel.Children.Clear()
rootPanel.Children.Add(new ErrorPage(msg)))
this.UnhandledException.Add(fun args ->
args.Handled <- true
try
let msg = args.ExceptionObject.Message + args.ExceptionObject.StackTrace
let errmsg = msg.Replace('"','\'').Replace("\r\n",@"\n")
"throw new Error(\"Unhandled error in Silverlight 2 Application " + msg + "\");"
|> HtmlPage.Window.Eval |> ignore
with _ -> HtmlPage.Window.Eval("throw new Error(\"Custom Error!\");") |> ignore)
end
1 comment:
Grateful to check out your website, I seem to be ahead to more excellent sites and I wish that you wrote more informative post for us. Well done work.
Post a Comment