Dynamically Size Silverlight Control on Webpage - asp.net

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 users 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

Related

Where to place the javascript code for content page in ASP.NET when using the master page

I want to use a image slider in my web page, the problem is that when I use the JS code with the master page it doesn't work, it works for page without master page. I tried placing the JS code in master page head section and in the content page in
, neither works.
I am using below js code.
<script language="javascript" type="text/javascript">
var i = 1;
function fun() {
i++;
document.getElementById("img1").src = "images/" + i + ".jpg";
if (i == 4) //here 2 is number of images i want to display in the slide show
{ i = 0; }
}
setInterval("fun()", 2000);
</script>
asp:Image I am almost sure that your problem is with the ids.
Master Page implements the INamingContainer interface, so Controls inside a Page with a Master Page are rendered with a nested id. Something like:
<img name="ctl00$MainContent$img1" id="ctl00_MainContent_img1" />
against what you get in a Page without Master Page
<img name="img1" id="img1" />
It is done this way to guarantee the ids of the controls to be unique within an entire application.
Any control that implements this interface creates a new namespace in which all child control ID attributes are guaranteed to be unique within an entire application. The marker provided by this interface allows unique naming of the dynamically generated server control instances within the Web server controls that support data binding.
You can get the ClientID of a control in Page with the ClientID property.
Your code will look something like:
<script language="javascript" type="text/javascript">
var i = 1;
function fun() {
i++;
document.getElementById("<%= img1.ClientID %>").src = "images/" + i + ".jpg";
if (i == 4) //here 2 is number of images i want to display in the slide show
{ i = 0; }
}
setInterval("fun()", 2000);
</script>
<asp:Image ID="img1" runat="server" />
You can also can set the ClientIDMode of your control to Static when declaring it and it will keep the id you assigned:
<script language="javascript" type="text/javascript">
var i = 1;
function fun() {
i++;
document.getElementById("img1").src = "images/" + i + ".jpg";
if (i == 4) //here 2 is number of images i want to display in the slide show
{ i = 0; }
}
setInterval("fun()", 2000);
</script>
<asp:Image ID="img1" runat="server" ClientIDMode="Static" />
But be warned that you have to do all the work to assure that the ids are not duplicated if you use this last method.
It does not worki because probably the ID of the control you are trying to get using getElementById is different when it get rendered on the page.
more info here
I would not use this approach anyway because you could have cross-browser issue.
I would use a JQuery plug-in instead
When you use masterpage, all aspxcontrols name change (when it get rendered)
if you wanna reach some controls, you have to use controlname.ClientID

Generic Handler not getting called in asp.net

I am trying to display an image from my database. I have an generic handler to display the image. But my problem is that it doesn't get called. My code for calling the handler is
Image1.ImageUrl = "~/ShowImage.ashx?id=" + id;
where id is a number and ShowImage.ashx is the handler. The breakpoints in .ashx file doesn't get hit either. I am new to asp.net. So any help would be highly appreciated.
In this cases the steps that you need to follow is to see how the html is rendered.
So, right click on the html page, and "view page source".
There locate the point that the ShowImage.ashx is called, and see if the full rendered path is correct.
From there you simple correct the path.
Additional you can use the browser tools to see what browser looks for, and if he finds it or not. On google chrome for example you make right click, then inspect elements and then click on the network. There you can see with red, what files your page can not find, and you need to fix the path.
Check this sample Example code this might help you.
ASPX Code :
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>
HTTP Handler class Impliment in Img tag
</h1>
<h1>Id : 1</h1>
<img src="ImageHandler.ashx?id=1" alt="Dynamic Image" />
<h1>Id : 2</h1>
<img src="ImageHandler.ashx?id=2" alt="Dynamic Image" />
</div>
</form>
</body>
</html>
C# Examples (ImageHandler.ashx File) :
<%# WebHandler Language="C#" Class="ImageHandler" %>
using System;
using System.Web;
public class ImageHandler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
//context.Response.ContentType = "text/plain";
//context.Response.Write("Hello World");
context.Response.ContentType = "image/jpeg";
if (context.Request.QueryString["id"] == "1")
{
context.Response.WriteFile("bamboo.jpg");
}
else
{
context.Response.WriteFile("palmtree.jpg");
}
}
public bool IsReusable {
get {
return false;
}
}
}
Here is live downloadable C# Examples and VB.Net Examples of this. Click Here...

Set document background image in code

I can use VS designer to open the document properties and change the Background property. But I can't seem to find a way to change it dynamically when the page loads. Can this be done in codebehind or this must be done in JavaScript only?
You can use the background and, more specifically, the background-image CSS properties.
http://www.w3schools.com/cssref/pr_background-image.asp
You can either generate the relevant HTML output on the server (using ASP.NET code) or in the browser, using JavaScript. Your HTML will look something like this:
...
<body style="background-image:url('...')">
...
</body>
...
You can try this on the markup:
<head runat="server">
<title></title>
<asp:Literal ID="Literal1" runat="server"></asp:Literal>
</head>
<body class="bodyStyle">
And this in the codebehind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
String ImgUrl = "/Images/image.png";
Literal1.Text = "<style>.bodyStyle {background-image: url('" + ImgUrl + "');}</style>";
}
}
You can programmatically change the image url as needed

Running random pictures in ASP.NET site

I'm building a web application and I have a question.
I want to display to the user running Random pictures in the Web Page.
how can I do this if it is possible.
thanks.
If you want to use a built-in control, you should look at the AdRotator. It will allow you to setup a XML file that lists all of your images that will be random displayed when the control renders on the page.
Control Usage:
<asp:AdRotator id="AdRotator1" runat="server" Target="_self"
AdvertisementFile="~/App_Data/Ads.xml"/>
Example XML File ( Ads.xml ):
<Ad>
<ImageUrl>~/Images/image1.jpg</ImageUrl>
<height>60</height>
<width>190</width>
<NavigateUrl>http://www.microsoft.com</NavigateUrl>
<AlternateText>Microsoft Main Site</AlternateText>
<Impressions>80</Impressions>
<Keyword>Topic1</Keyword>
</Ad>
<Ad>
<ImageUrl>~/Images/image2.jpg</ImageUrl>
<height>90</height>
<width>90</width>
<NavigateUrl>http://www.wingtiptoys.com</NavigateUrl>
<AlternateText>Wingtip Toys</AlternateText>
<Impressions>80</Impressions>
<Keyword>Topic2</Keyword>
</Ad>
</Advertisements>
If your looking for something that can change the images client side (via JavaScript), there are a ton of solutions available. Here is an example of using the jQuery.Cycle plugin.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="jQueryRotateImages.aspx.cs" Inherits="DevOne.jQueryRotateImages" %>
<!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>jQuery Rotate Images - Cycle Plugin</title>
<style type="text/css">
.slideshow { height: 232px; width: 232px; margin: auto; }
.slideshow img { padding: 15px; border: 1px solid #ccc; background-color: #eee; }
</style>
<!-- include jQuery library -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<!-- include Cycle plugin -->
<script type="text/javascript" src="http://cloud.github.com/downloads/malsup/cycle/jquery.cycle.all.latest.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('.slideshow').cycle({
fx: 'fade' // choose your transition type, ex: fade, scrollUp, shuffle, etc...
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div id="slideshow" class="slideshow" runat="server">
</div>
</form>
</body>
</html>
And here is how you can add your images dynamically in your code behind.
using System;
using System.Web.UI.HtmlControls;
namespace DevOne
{
public partial class jQueryRotateImages : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
slideshow.Controls.Add(new HtmlImage() { Src = "http://cloud.github.com/downloads/malsup/cycle/beach1.jpg", Width = 200, Height = 200});
slideshow.Controls.Add(new HtmlImage() { Src = "http://cloud.github.com/downloads/malsup/cycle/beach2.jpg", Width = 200, Height = 200 });
slideshow.Controls.Add(new HtmlImage() { Src = "http://cloud.github.com/downloads/malsup/cycle/beach3.jpg", Width = 200, Height = 200 });
}
}
}
pseudocode:
//On Page Load do this:
//create list of images from whatever your image source is
//generate a random number between 0 and `ImageList.Length - 1`
//assign the url from the image at the random index to the ImageUrl property of your Image control
If you simply want to pull a random image from a folder on the website, you could do something like the following:
string[] files = Directory.GetFiles(Server.MapPath(#"/images/"));
Random r = new Random();
string imageName = files[r.Next(files.Length);
// ... Code to display image.
However, you've really given sparse information of what you're trying to accomplish, such as where the images are coming from. This would be a very generic solution.
The following blog of msdn explains all the basics about the Random()
MSDN Microsoft Developer Network: Random()
The basic about it is that the Random class selects a random number from an array. It depends on the ticks time. MSDN DateTime Ticks
The ticks are used basically to generate a random. Random can be used as: Suppose I am extracting data from database. It will be
var db = Database.Open("databasename")
var image = db.Query("SELECT * FROM Images").ToList();
var randomImage = image[new Random().Next(image.Count)]
And display the data of it.

asp.net custom control rendering outside of form tag

I am having an issue with a custom control rendering its contents (child controls) outside of the tag which leads to runtime errors and issues. In an attempt to simplify things as much as I can, I created the control below but it has the very same issue. I have tried inheriting from Control, WebControl and CompositeControl all resulting in with the same problem. Guessing there is something obvious that I am doing wrong... Thanks for any help.
using System;
using System.Web.UI.WebControls;
namespace MyControls
{
public class TestControl : CompositeControl
{
protected override void CreateChildControls()
{
Controls.Clear();
Controls.Add(new Button() { Text = "TestControl!" });
ClearChildViewState();
}
}
}
Adding the control programmatically results in markup outside the forms tag. Adding the control via markup works correct.
protected void Page_Load(object sender, EventArgs e)
{
Controls.Add(new TestControl());
}
...
<body>
<form name="PageForm" method="post" action="default.aspx" id="PageForm">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTE5MDEwMTE5MWRkg0FopdvLhTPGxHkGm1xCCOVQz6A=" />
</div>
<div>
</div>
</form>
</body>
</html>
<span><input type="submit" name="ctl04$ctl00" value="TestControl!" /></span>
Adding the control through the Page.Form property will render the button inside the form.
Page.Form.Controls.Add(new Button() { Text = "TestControl!" });
However, since the button is not contained within a block, such as a <div>, you might have some layout issues with this button. Use ScarletGarden's approach.
This has nothing to do with your custom control. Your problem is caused by how you're adding the control to the page.
When you call Controls.Add in your page's Page_Load method, this is basically shorthand for:
Page.Controls.Add(new TestControl());
ie, You're adding the control at the end of your entire page's control hierarchy. When the page is rendered, your control is rendered after all the others - even after the closing </html> tag.
If you want your control to be rendered inside the form then you need to add it to the form's control hierarchy instead:
Form.Controls.Add(new TestControl());
If you need even more fine-grained positioning, then you need to put a placeholder (or div or span etc) on your page in the required position and add your control to that, as in ScarletGarden's answer.
Your control seems ok, I think you have a problem with adding your control to your page,
Add a placeHolder to your page,
<body>
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="placeHolder" runat="server"></asp:PlaceHolder>
</div>
</form>
</body>
and then add your composite control to this placeholder's controls collection like that :
TestControl testCtrl = new TestControl();
placeHolder.Controls.Add(testCtrl);

Resources