Widget template code behind
I'm using the following post to add code behind to a widget template built from the module builder.
http://www.sitefinity.com/devnet/forums/sitefinity/developing-with-sitefinity/howto-guide-add-code-behind-to-a-sitefinity-widget-template.aspx
I need to add a rad rotator to the widget template but I can't figure out how to specify the data source.
Has anyone tried this yet?
Whats not working?
Yes, I tried but couldn't figure it out. For example, in my custom module I have a media field that I can upload multiple images to. I was hoping I could do something like Datasource='<%# Eval("Images") %>' but that doesn't work.
Can you paste the template and codebehind?
Template
<%@ Control Language="C#" Inherits="SitefinityWebApp.WidgetTemplates.Wallpaper.Wallpaper" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.DynamicModules.Web.UI.Frontend" TagPrefix="sf" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields" TagPrefix="sf" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sf" %>
<
div
id
=
"wallpaper"
>
<
sf:DynamicDetailContainer
id
=
"detailContainer"
runat
=
"server"
>
<
LayoutTemplate
>
<
div
class
=
"sfitemDetails"
>
<
h1
><
sf:SitefinityLabel
ID
=
"mainShortTextFieldLiteral"
runat
=
"server"
Text='<%# Eval("Title") %>' WrapperTagName="h1" HideIfNoText="true" CssClass="sfitemTitle" /></
h1
>
<
telerik:RadRotator
ID
=
"rtrImages"
runat
=
"server"
Width
=
"850px"
Height
=
"333px"
ItemHeight
=
"333px"
ItemWidth
=
"850px"
ScrollDirection
=
"Up"
FrameDuration
=
"5000"
SlideShowAnimation-Type
=
"Fade"
SlideShowAnimation-Duration
=
"750"
PauseOnMouseOver
=
"false"
RotatorType
=
"SlideShow"
OnDataBound
=
"rtrImages_DataBound"
DataSource='<%# Eval("Images") %>'>
<
ItemTemplate
>
<
img
id
=
"displayImage"
runat
=
"server"
src
=
""
alt
=
""
/>
</
ItemTemplate
>
</
telerik:RadRotator
>
<
sf:SitefinityLabel
runat
=
"server"
Text='<%# Eval("Description")%>' WrapperTagName="div" HideIfNoText="true" CssClass="sfitemLongText" />
<
sf:AssetsField
runat
=
"server"
DataFieldName
=
"Images"
/>
</
LayoutTemplate
>
</
sf:DynamicDetailContainer
>
</
div
>
<
asp:PlaceHolder
ID
=
"socialOptionsContainer"
runat
=
"server"
></
asp:PlaceHolder
>
namespace SitefinityWebApp.WidgetTemplates.Wallpaper
public partial class Wallpaper : System.Web.UI.UserControl
//protected override void OnInit(EventArgs e)
//
// base.OnInit(e);
// var rotator = (RadRotator)this.FindControl("rtrImages");
// rotator.ItemDataBound += new RadRotatorEventHandler(rotator_ItemDataBound);
//
protected void Page_Load(object sender, EventArgs e)
//protected void rotator_ItemDataBound(object sender, RadRotatorEventArgs e)
//
// var args = (RadRotatorItem)e.Item;
// var imageCtl = (Image)e.Item.FindControl("displayImage");
// imageCtl.ImageUrl = GetImageUrl(args);
//
//protected string GetImageUrl(object item)
//
// var retval = string.Empty;
// var wallpaperRotator = item as DynamicContent;
// if (wallpaperRotator == null) return retval;
// var contentLinks = (ContentLink[])wallpaperRotator.GetValue("Images");
// var imageContentLink = contentLinks.FirstOrDefault();
// var libraryManager = LibrariesManager.GetManager();
// var image = libraryManager.GetImage(imageContentLink.ChildItemId);
// if (image == null) return retval;
// retval = image.Url;
// return retval;
//
Do you get breakpoints hit?
Yes
Try something like this...keeping in mind...I just free-handed this so it might not initially build...might be a typo in there, dont forget the using Telerik.Sitefinity and Telerik.Sitefinity.Model
private DynamicContent _case = null;
protected void Page_Init(object sender, EventArgs e)
//Get the data item
DynamicContent[] detailItems= (DynamicContent[])detailContainer.DataSource;
_case = detailItems[0];
//Hook into the databound of the detail control itself
detailContainer.DataBound += new EventHandler(detailContainer_DataBound);
protected void detailContainer_DataBound(object sender, EventArgs e)
RadRotator rtrImages = ((DetailItem)this.detailContainer.Controls[0]).FindControl("rtrImages") as RadRotator;
var images = _case.GetValue("Images"); //Check to see what comes back here, might need to GetValue<
T
> instead
rtrImages.DataSource = images;
trtImages.DataBind(); //Pretty sure this is needed
Changed it to the following and I'm getting Unable to cast object of type 'System.Web.UI.LiteralControl' to type 'Telerik.Sitefinity.DynamicModules.Web.UI.Frontend.DetailItem'. on line
RadRotator rtrImages = ((DetailItem)this.Controls[0]).FindControl("rtrImages") as RadRotator;
private DynamicContent _case = null;
protected void Page_Init(object sender, EventArgs e)
var container = (DynamicDetailContainer)this.FindControl("detailContainer");
//Get the data item
DynamicContent[] detailItems = (DynamicContent[])container.DataSource;
_case = detailItems[0];
//Hook into the databound of the detail control itself
container.DataBound += new EventHandler(detailContainer_DataBound);
protected void detailContainer_DataBound(object sender, EventArgs e)
var container = (DynamicDetailContainer)this.FindControl("detailContainer");
RadRotator rtrImages = ((DetailItem)this.container.Controls[0]).FindControl("rtrImages") as RadRotator;
var images = _case.GetValue("Images"); //Check to see what comes back here, might need to GetValue<
T
> instead
rtrImages.DataSource = images;
rtrImages.DataBind(); //Pretty sure this is needed
Can you try putting the
<
div
id
=
"wallpaper"
>
<
LayoutTemplate
>?
Also you dont need to re-get the container with find in databound you can do it with var container = sender as
DynamicDetailContainer; ...just cast it instead of re-find.Hey Steve. First, thanks for all the help. I think I'm almost there. I moved the div inside the layouttemplate. Here's the updated code.
protected void Page_Init(object sender, EventArgs e)
var container = (DynamicDetailContainer)this.FindControl("detailContainer");
//Get the data item
DynamicContent[] detailItems = (DynamicContent[])container.DataSource;
_case = detailItems[0];
//Hook into the databound of the detail control itself
container.DataBound += new EventHandler(detailContainer_DataBound);
protected void detailContainer_DataBound(object sender, EventArgs e)
var container = sender as DynamicDetailContainer;
RadRotator rtrImages = ((DetailItem)container.Controls[0]).FindControl("rtrImages") as RadRotator;
var images = _case.GetValue("Images"); //Check to see what comes back here, might need to GetValue<
T
> instead
rtrImages.DataSource = images;
rtrImages.DataBind(); //Pretty sure this is needed
Oook yeah if you look at what it's giving you it's a contentlink object.
That's what that AssetsField control in your markup is for, reads those links and the link tells it what to go resolve..it's like a generic FK object...so you'll just need to resolve those guys back to images then give that to your rotator.
Just use the ChildItemId property of each of those to query the images module (like you did in your GetImageUrl method). So you're now left with 4 Images instead of 4 ContentLinks.