Dynamically Size Silverlight Control on Webpage
Here is the issue...
I am adding some silverlight 3 controls to an ASP.Net Web Forms application. The silverlight application's height can change based on the amount of data in it. The application is part of a web page and not the whole page. My user开发者_运维技巧s would like to have only 1 set of scroll bars. Is there a way to dynamically size the div or object based on the suze of the silverlight application?
For example can I hook into the silverlight javascript to do this somehow?
There are two ways to do it: either by accessing the DOM element directly and changing its style (or css) attributes, or by calling a javascript function on the page which will do the same thing. Below i have the xaml, code behind, and the HTML for a simple example which when you drag a slider in the silverlight control, it resizes the div that contains the control. If you create a simple Silverlight Application with a complementary test website and page, and then copy and paste the following code in then you can have a play (note that i have snipped some of the generated styles/script from the aspx page for the sake of brevity).
The C# and javascript code is not particularly pretty or bullet proof, it is simply an example.
<UserControl x:Class="SilverlightApplication6.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="200" d:DesignHeight="480">
<Grid x:Name="LayoutRoot">
<Slider x:Name="WidthSlider" Value="50" Maximum="200"></Slider>
</Grid>
</UserControl>
Code behind for the Silverlight application:
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
WidthSlider.ValueChanged += new RoutedPropertyChangedEventHandler<double>(WidthSlider_ValueChanged);
}
private void WidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
//access and manipulate the DOM element directly:
HtmlElement container = HtmlPage.Document.GetElementById("silverlightControlHost");
if (container != null)
{
container.SetStyleAttribute("width", (50 + e.NewValue).ToString() + "px");
}
//pass a delta value to the js function, which will get added to the current width of the container:
HtmlPage.Window.Invoke("resizeContainer", (e.NewValue - e.OldValue).ToString());
}
}
and the aspx page:
<%@ Page Language="C#" AutoEventWireup="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>SilverlightApplication6</title>
<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript">
function resizeContainer(delta) {
var container = document.getElementById('silverlightControlHost');
if (container != null) {
//alert('starting width: ' + container.style.width);
container.style.width = (parseInt(container.style.width) + Number(delta) + 'px');
//alert('finishing width: ' + container.style.width);
}
}
</script>
</head>
<body>
<form id="form1" runat="server" style="height:100%">
<div id="silverlightControlHost" style="border: solid 1px red; width:200px; height: 400px;">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="ClientBin/SilverlightApplication6.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40624.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
</form>
</body>
</html>
Edit: Two days after i wrote this answer Charles Petzold wrote a blog post about resizing silverlight controls within the html page, you can find it here. The main difference is that he resizes the actual silverlight plugin control, while i was resizing the html element that the silverlight plugin resides within.
I do something similar with a silverlight control I have made. My problem was I have a control to show document scans in a silverlight control and I had the height hardcoded but some users run at a much higher resolution so they had a lot of wasted space they could use.
So I implemented a little client side javascript function that figures out the optimal size for the control. This code runs on page load.
At the bottom of your HTML page add the following code (using Jquery):
<script type="text/javascript" language="javascript">
function InitializeSilverlightControlHeight()
{
$(function()
{
var miniumimControlSize = 500;
var pagePadding = 150;
var screenheight = $(window).height() - pagePadding;
if (screenheight > miniumimControlSize)
{
$("#yourSilverLightControlName").height(screenheight);
}
});
}
InitializeSilverlightControlHeight();
</script>
What this does is it checks the browser window's viewable size and then minuses the padding amount (which in my case is 150px to account for the header's height). If this size is larger than the minimum size of the control it sets the control to this size.
Hope that helps or at least points you in a general direction to get you rolling.
Don't think this is quite what you're looking for but it might help...
In the ctor of your the first page your silverlight control creates you can add an event
App.Current.Host.Content.Resized += new EventHandler(Content_Resized);
Then in your event listener you can resize the control to fit the window better.
void Content_Resized(object sender, EventArgs e)
{
double height = App.Current.Host.Content.ActualHeight;
double width = App.Current.Host.Content.ActualWidth;
this.Height = height;
this.Width = width;
m_currentPage.Height = height;
m_currentPage.Width = width;
}
Hope that helps =D
精彩评论