views:

1886

answers:

2

I am using WPF and Silverlight BookControls by Mitsu

http://www.codeplex.com/wpfbookcontrol

The WPF example alows that every page in the book to be a XAML file, but the Silverlight example dont.

Is there a way load a XAML in every book page in the Silverlight example ?

A: 

Load the XAML dynamically by using the following code/process:

System.Windows.Application.LoadComponent(this,
new System.Uri("/SilverlightApplication1;component/MyPage.xaml",
System.UriKind.Relative));

where "SilverlightApplication1" is the project name & "MyPage.xaml" is the XAML page you want to load dynamically. Then you have to do FindName() to get the inner controls:

Grid LayoutRoot = ((Grid)(FindName("LayoutRoot")));
TextBlock testTextBlock = ((TextBlock)(FindName("testTextBlock")));

also see http://silverlight.net/learn/learnvideo.aspx?video=56933

EDIT: Expanded explaination

First of all, the string containing the XAML fragment must contain only one root element. And that node must include a namespace reference to http://schemas.microsoft.com/client/2007. If you forget to reference that namespace, you'll get a XamlParseException when you attempt to load the XAML. As an example, look at the following C# code which creates a TextBlock object:

string xamlText="<TextBlock xmlns=\"http://schemas.microsoft.com/client/2007\" " +
"Text=\"Hello World!" \"/>";
TextBlock txt = System.Windows.Markup.XamlReader.Load(xamlText) as TextBlock;

In this code, the XAML text fragment contains the necessary namespace reference and an attribute setting the Text property to "Hello world!" The XamlReader class in the System.Windows.Markup namespace is then used to load up the XAML text using the Load method which returns a System.Object. Since the root node of the XAML text was a TextBlock, the resultant object is actually an instance of the System.Windows.Controls.TextBlock type. So the cast to that type succeeds, yielding a disconnected TextBlock.

I say that the new TextBlock is "disconnected" because just after it is created, it is not associated with any other UIElement. Controls are not really usable until they are connected to a canvas and ultimately to an application. Most XAML controls have a property called Children which is a UIElementCollection. That collection's Add method can be use to attach the new TextBlock and render it. Of course, casting the result of the Load method to a TextBlock isn't necessary. But to be attached via the UIElementCollection.Add method, you'll have to cast the Load result to the UIElement base class at a minimum.

almog.ori
I am getting this error "Xaml Parse Exception AG_E_PARSER_BAD_TYPE" in this line: System.Windows.Application.LoadComponent(this, new System.Uri("/SLBookDemoApp;PagTeste2.xaml", System.UriKind.Relative));
Code Burn
That jsut means there's something wrong with the syntax of the Xaml you're trying to load.
mattmanser
What kind of XAML shoul I use, and what sould it look like ?Any example ?
Code Burn
Be careful, you're going to run into XAML compatibility issues: a lot of controls (think DockPanel) aren't in Silverlight by default, and even with the Silverlight Toolkit installed, they'll have a different Xmlns prefix and assembly name. To really create a compatible book-reading format, you'll likely need to do on-the-fly (think Linq) conversion of some of the elements to go from WPF to Silverlight-friendly.
Jeff Wilcox
A: 

I have this Page.xaml

<UserControl x:Class="SLBookDemoApp.Page"
    xmlns="http://schemas.microsoft.com/client/2007" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:SLMitsuControls;assembly=SLMitsuControls"
    Width="800" Height="600" Loaded="UserControl_Loaded">
    <Grid>
     <local:UCBook x:Name="book" Margin="50" />
    </Grid>
</UserControl>

And the correspondent Page.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SLMitsuControls;

namespace SLBookDemoApp
{
    public partial class Page : UserControl, IDataProvider
    {
        public Page()
        {
            InitializeComponent();
        }

        private List<Grid> pages;

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            /*
             pages = new List<Button>
            {
                new Button { Content = "Page 0"},
                new Button { Content = "Page 1", Background = new SolidColorBrush(Colors.Green) },
                new Button { Content = "Page 2", Background = new SolidColorBrush(Colors.Yellow) },
                new Button { Content = "Page 3", Background = new SolidColorBrush(Colors.Brown) },
                new Button { Content = "Page 4", Background = new SolidColorBrush(Colors.Magenta) },
                new Button { Content = "Page 5", Background = new SolidColorBrush(Colors.Red) }
            };
             */

            System.Windows.Application.LoadComponent(this, new System.Uri("/SLBookDemoApp;PagTeste2.xaml", System.UriKind.Relative));
            Grid LayoutRoot = ((Grid)(FindName("LayoutRoot")));
            //TextBlock testTextBlock = ((TextBlock)(FindName("testTextBlock")));

            pages = new List<Grid>
            {
            };

            pages.Add(LayoutRoot);
            /*
            int i = 0;
            foreach (var b in pages)
            {
                if (i % 2 == 0)
                    b.Click += Button_Click;
                else
                    b.Click += Button_Click_1;
                i++;
            }
            */

            book.SetData(this);
        }

        #region IDataProvider Members

        public object GetItem(int index)
        {
            return pages[index];
        }

        public int GetCount()
        {
            return pages.Count;
        }

        #endregion

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            book.AnimateToNextPage(500);
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            book.AnimateToPreviousPage(500);
        }
    }
}

And the XAML I wnat to include is this PagTeste2.xaml

<Grid
        xmlns="http://schemas.microsoft.com/client/2007" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        x:Class="SLBookDemoApp.PagTeste2"
        x:Name="LayoutRoot">
        <Rectangle Width="192" Height="80" Fill="#FF8F0A0A" Stroke="#FF000000" Canvas.Left="224" Canvas.Top="104"/>

</Grid>

With the correspondent PagTeste2.xaml.cs

using System;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
//using System.Windows.Navigation;
using SLMitsuControls;

namespace SLBookDemoApp
{
    public partial class PagTeste2
    {
     public PagTeste2()
     {
      this.InitializeComponent();

      // Insert code required on object creation below this point.
     }
    }
}

I am getting an error on this line

System.Windows.Application.LoadComponent(this, new System.Uri("/SLBookDemoApp;PagTeste2.xaml", System.UriKind.Relative));

Anyone knows why ?

Code Burn