views:

135

answers:

1

update 5: brians solution worked:

namespace Module1
type Page1() as this =
    inherit UserControl()
    let uriStr = "/FSSilverlightApp;component/Page1.xaml"
    let uri = new System.Uri(uriStr, System.UriKind.Relative)
    do
        Application.LoadComponent(this, uri)

    member public this.Uri with get () = uri

type MyApp() as this =
    inherit Application() 
        do Application.LoadComponent(this, new System.Uri("/FSSilverlightApp;component/App.xaml", System.UriKind.Relative))  

        let nav : Frame = siteTemplate ?  contentFrame
        let p1 = new Module1.Page1() ;

        member this.navigate ea =
             nav.Navigate(p1.Uri)


<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             x:Class="Module1.MyApp">
    <Application.Resources>
    </Application.Resources>
</Application>

<UserControl x:Class="Module1.Page1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;

    <Grid x:Name="LayoutRoot" Background="White">
        <TextBlock Text="This is page 1 Lets see if we can ever get here!!!" FontSize="24" />
    </Grid>
</UserControl>

update 4:

the template Brian has mentioned is mostly doing the trick. I still have a more complex page that is giving me troubles - yet it is most likely my code. Once my code is complete I will post what I can diagnose but the parts include:

  1. Setting App.XAML correctly (referencing your application object correctly)
  2. in post construction of your application object use Application.Load to load the App.xaml
  3. In your application object create instances of your page xaml
  4. in post construction of your page objects use Application.Load to load the individual page.xaml
  5. each of your page objects should extend UserControl; I suspect this is not truly the case - once I get more more complex page running I will see if removing this restriction will have an effect.

update 3:

I implemented my own controller logic in the Application object, which seems to do part of the trick (and solve my needs for a prototype anyhow).

type Page1() as this =
    inherit Page()

    do
        this.Content <- loadXaml("Page1.xaml")

type MyApp() as this =
    inherit Application()
    let cc = new ContentControl()

    let mainGrid : Grid = loadXaml("MainWindow.xaml")
    let siteTemplate : Grid = if mainGrid.Name = "siteTemplate" then mainGrid else mainGrid ?  siteTemplate
    let nav : Frame = siteTemplate ?  contentFrame

    let page1  = new Module1.Page1() :> Page ;
    let page2  = new Module1.Page2() :> Page ;
    let page3  = new Module1.Page3() :> Page ;

    do
        this.Startup.Add(this.startup)

        // to be able to get focus
        cc.IsTabStop <- true
        cc.IsEnabled <- true

        System.Windows.Browser.HtmlPage.Plugin.Focus()
        cc.Content <- mainGrid
        this.RootVisual <- cc

    member this.startup ea = 
        menu.MenuItemClicked.Add(this.navigate)
        resolutionSlider.SizeChanged.Add(this.resizeTemplate)

    member this.navigate ea = 
        if ea.Index = 1 then nav.Content <- page1
        elif ea.Index = 2 then nav.Content <- page2
        elif ea.Index = 3 then nav.Content <- page3

It works... I don't know the implication on memory / performance. I wonder if the navigation fw handles the construction / destruction of page objects more efficiently than what I did. I think the navigation FW works nicely with the browsers back and forward buttons - which my solution doesn't.


update 2: it looks as though teh C# applciation implments

 public void  InitializeComponent() 

which loads and the XAML. Though I am no IL expert; I will make the similar changes on the F# side... I wonder if it is the partial class concept. One theory I am working on is:

page.xaml.cs is definitely a partial class - you can read it in the source.

page.xaml has an attribute that refers back to the c# class. I wonder if the special build commands treat this as a partial class - by parsing it and creating 1) any member component references 2) intialComponent() method which registers the page wherever it needs to be registered?


Update 1: After a nights sleep the problem can be stated more accurately as I have a 100% f# / silverlight implementation and am looking to use the built in Navigation components. C# creates page.xaml and page.xaml.cs um - ok; but what is the relationship at a fundamental level? How would I go about doing this in f#?

The applcuation is loaded in the default module, and I pull the XAML in and reference it from the application object. Do I need to create instances / references to the pages from within the application object? Or set up some other page management object with the proper name value pairs?

When all the Help of VS is stripped away - what are we left with?


original post (for those who may be reading replies)

I have a 100% silverlight 3.0 / f# 2.0 application I am wrapping my brain around. I have the base application loading correctly - and now I want to add the naigation controls to it.

My page is stored as an embedded resource - but the Frame.Navigate takes a URI. I know what I have is wrong but here it is:

let nav : Frame = mainGrid ?  mainFrame
let url = "/page1.xaml"
let uri = new System.Uri(url, System.UriKind.Relative) ;
nav.Navigate uri

Any thoughts?

A: 

Have you tried making the Xaml a file in the project with a BuildAction of Content rather than an EmbeddedResource? Honestly, I've no clue if that works, but it might get packaged into the .xap that way, and then the relative uri might work. How would it work in a C# project? Try that.

EDIT

Aha, Dmitry's template appears to have this figured out. He has Xaml files with BuildAction of Resource, and then code like

type MainPage() as this =
    inherit UserControl()
    do
        Application.LoadComponent(this, 
            new System.Uri("/SilverlightApplication3;component/Page.xaml", 
                           System.UriKind.Relative))
    let layoutRoot : Grid = downcast this.FindName("LayoutRoot")

    do 
        ()

to load it.

Brian
Y i guess 1/2 a day later that is the question. How does it work in a C# application? There is the XAML and the CS that get bound somehow and stuck somewhere that the Navigation components are aware of. What is the XAP? How do things get in there? Is there way to inspect it similar to ildasm?Very fun / frustrating / interesting project. I am learnign alot about f# and XAML along the way - I guess I am missing the education on silverlight. And the web is missing how components in silverlight work - but is flooded with how to use components in silverlight.
akaphenom
Um including the page as content doesnt work either. Maybe I should retitle / reask the question?
akaphenom
See my recent edit.
Brian
Awsome Brian I will check that out. I ended up building my own controller functionality inside of the App object - I am goign to update my original post with what I ended up with to have as much as what was tried and did (and did not) work in one place.Honestly, I don't want to invent my own controller - but I guess I don't know the value of the SL Navigation stuff. Will find out sonn though. I might not get to trying the implemntation you referecned until this weekend.
akaphenom