I am working on making a very simple IFrame control for silverlight.
Goal: Control the placement of an IFrame overlayed on a silverlight application
The silverlight IFrame control is being used inside a silverlight application that allows the user to build a search query, then a url is formed from the search query and set to be the source of the IFrame. It's a basic search application.
I want the IFrame to change size and position based on the size and position of the silverlight control.
I found code here: http://www.kirupa.com/blend_silverlight/absolute_position_transformtovisual.htm, that I put in the constructor of the silverlight control to get the position of the control relative to the silverlight application. I then use that position to set the IFrameLeft and IFrameTop dependency properties of the silverlight control.
this.LayoutUpdated += (obj, args) =>
{
GeneralTransform gt = HtmlViewerStackPanel.TransformToVisual(null);
Point point = gt.Transform(new Point());
IFrameLeft = (int)point.X;
IFrameTop = (int)point.Y;
};
Then in the SizeChanged event I have the following which makes the changes to the IFrame. In the constructor I set FrameID to be a new Guid. Then create an IFrame with that Guid as the id.
private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
{
IFrameHeight = (int)this.ActualHeight;
IFrameWidth = (int)this.ActualWidth;
var iframeElement = System.Windows.Browser.HtmlPage.Document.GetElementById(this.IFrameID);
iframeElement.SetStyleAttribute("width", string.Format("{0}px", IFrameWidth));
iframeElement.SetStyleAttribute("height", string.Format("{0}px", IFrameHeight));
}
It only works as desired if the silverlight application takes up the whole browser window. However that is not how I most commonly use it.
From reading this question: Getting absolute position of an element relative to browser, it appears that if I could get a reference to the object tag HtmlElement that the silverlight application is hosted in I could read the offsetleft and offsettop properties. If I had the position of the object tag relative to the browser it seems like I could very easily calculate the silverlight control's offset from the browser. Since I can determine the silverlight control's offset from the silverlight application.
In the past I have just given the object, or a wrapping div tag an id and then used the HtmlPage.Document.GetElementById to get a reference to the element. I'd like to avoid that if possible.
I tried this in the LayoutUpdated event after getting the GeneralTransform and setting the IFrame Left and Top. It gets the object tag and uses the offset properties I talked about before.
var objectElements = System.Windows.Browser.HtmlPage.Document.GetElementsByTagName("object");
if (objectElements.Count == 1)
{
var objElement = objectElements.Single();
do
{
IFrameLeft += Convert.ToInt32(objElement.GetProperty("offsetLeft"));
IFrameTop += Convert.ToInt32(objElement.GetProperty("offsetTop"));
} while ((objElement=(System.Windows.Browser.ScriptObject)objElement.GetProperty("offsetParent")) != null);
}
Using the object tag to get the offset from the browser window works, I was having some problems with one of the pages I tested it on then I learned that the offsets are from offsetparent instead of always from the browser window. I added the code to loop untill the offsetparent is null. The code now basicly works.
I want to be able to put the开发者_运维问答 silverlight control anywhere, and the IFrame be contained to the area of the control, and be at the position of the control.
I'm wide open to any ideas on a better approach to positioning the IFrame to match the silverlight control.
Here are a few more examples of what I'm trying to do:
- http://www.wintellect.com/cs/blogs/jlikness/archive/2010/09/19/hosting-html-in-silverlight-not-out-of-browser.aspx
- http://www.davidezordan.net/blog/?p=700
- http://csharp-snippets.blogspot.com/2009/03/html-host-control-in-silverlight.html
- http://www.codeproject.com/KB/silverlight/BlendPDFwithSilverlight.aspx
精彩评论