views:

3779

answers:

5

I have a silverlight app that I want to allow to size like a regular HTML page. That is, I want the size of the silverlight plugin to expand and contract in height to accommodate the dynamic data and controls that I am populating the silverlight app with. So, say I have a Page with a Grid and a button. The user hots the button and the grid gets a bunch of rows with images making the natural size of the grid higher than the browser windows. I would like to have something in place to resize the silverlight plugin to accomidate the DesiredSize of the Grid. The following, and several other attempts, are not working:

// handler in my main page.
 void MainGrid_LayoutUpdated(object sender, EventArgs e)
 {
     HtmlPage.Window.Invoke("setSilverlightSize", this.MainGrid.DesiredSize.Height);
 }

<body style="height:100%;margin:0;">
    <form id="mainForm" runat="server" style="height:100%;">
        <asp:ScriptManager ID="ScriptManager" runat="server"></asp:ScriptManager>
        <div id="SilverlightContainer"  style="height:100%;">
            <asp:Silverlight ID="SLMain" runat="server" Source="~/ClientBin/My.Silverlight.Main.xap" Version="2.0" Width="100%" Height="100%" />
        </div>
    </form>
    <script type="text/javascript">
        function setSilverlightSize(val) {
            var host = document.getElementById("SilverlightContainer");
            host.style.height = val + "px";
        }
    </script>
</body>

The desired size of the MainGrid always wants to be the size of the window. Argh said the pirate.

-r

A: 
  1. Set the overflow to "auto"
  2. Set the scroll to "no"
  3. Set the margin to "0"
  4. Set the containing div's width and height to "100%"
  5. Set the Silverlight control's width and height to "100%"

This should cover all your bases. See below for some sample HTML.

Try this:

<style type="text/css"> 
html, body { overflow:auto } 
</style>
<head>
    <title>My App</title>
</head>
<body id="bodyId" style="margin:0;" scroll="no">
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
         <div style="position: fixed; height: 100%; width: 100%">
            <avn:Silverlight 
                ID="xamlHost" 
                runat="server" 
                Source="~/ClientBin/THE.xap" 
                MinimumVersion="x.x.xxxxx" 
                Width="100%" 
                Height="100%" 
                />
         </div>
    </form>
</body>
</html>
markti
In this case, the silverlight plugin does not grow to accommodate the content. In the case where my content is bigger than the browser window, I would like the silveright plugin to grow past the borders of the browser window, if necessary, such that the browser will show scroll bars. In your example, the plugin scales with the browser window and not the silverlight content.
ptoinson
I see, this brings up the age old question of who should be responsible for scrolling, the browser? or Silverlight? I have found that it is much simpler to handle scrolling of content from within Silverlight. Which is why I use the above HTML container to ensure that only the Silverlight control does the scrolling. If you don't do it this way you could run into the vile double scrollbar scenario.
markti
Unfortunately, I want to use windowless mode for silverlight which does not allow the mouse to be captured outside the plugin. Using Silverlight scrolling here is buggy.
ptoinson
+1  A: 

I used this and seems to work well. Need to get Render"ed" size.

private void LayoutRoot_LayoutUpdated(object sender, System.EventArgs e)
{
    // Set the size of the SL object to the new rendered size of the Grid.
    ResizeSilverlightOnject(this.LayoutRoot.RenderSize.Height);
}

private void ResizeSilverlightObject( double height )
{
    HtmlPage.Window.Invoke( "ResizeObject", new object[] { height } );
}
staceyw
I've been trying this solution but seem to be getting the error..."Exception of type 'System.ExecutionEngineException' was thrown." when the application starts up.
Justin
For reference here is the code on the Silverlight side. public MainPage() { InitializeComponent(); LayoutRoot.LayoutUpdated += new EventHandler(LayoutRoot_LayoutUpdated); } private void LayoutRoot_LayoutUpdated(object sender, EventArgs e) { HtmlPage.Window.Invoke("ResizeSilverlightContainer", new object[] { this.LayoutRoot.RenderSize.Height }); }
Justin
A: 

Please change the name of the calling method ResizeSilverlightOnject to ResizeSilverlightObject , thanks

A: 

What about that ResizeObject javascript function?

Kostkac
A: 

If your trying to determine the height using a Validation Summary (slightly unrelated to this question, but useful), try this: In your Page.xaml.cs // store the original height in the Page_Loaded event

void Page_Loaded(object sender, RoutedEventArgs e)
{
        SetupPage();
        this.ValidationSummary.SizeChanged += new SizeChangedEventHandler(ValidationSummary_SizeChanged);
}
void ValidationSummary_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        if (this.OriginalPageHeight == 0.0)
        {
            this.OriginalPageHeight = this.RenderSize.Height;
        }
        else
        {
            double expandSize = this.OriginalPageHeight + e.NewSize.Height;
            ResizeSilverlightObject(expandSize);
        }
    }

EDIT: added Javascript function and cs function

    function ResizeObject(height) {
        var host = document.getElementById("uploaderHost");
        host.style.height = height + "px";
    }

public void ResizeSilverlightObject(double height)
    {
       HtmlPage.HtmlWindow.Invoke("ResizeObject", new object[] { height });

    }
Kevin