Ideas on how to use a MediaContentSelectorView in a User Con

Posted by Community Admin on 04-Aug-2018 20:42

Ideas on how to use a MediaContentSelectorView in a User Control

All Replies

Posted by Community Admin on 23-Mar-2012 00:00

I've been banging my head against the wall for a weeks trying to get a MediaContetSelectorView to work directly on a page without putting it in a custom control and I've finally succeeding in part.  I hope to put my findings in this thread so that others who have been asking the same questions as I, can try to glean the key information from my findings to apply it to their own code.  I do not however claim that this is the best approach or the even the most elegant solution as I had to cludge my way along to get here so any suggestion would be wonderful.

The most difficult piece for me to find to put together was how to get my user control to "act" like a custom control.  What tipped me off that this might be possible was the Page Selector Events thread.  Which then lead me to IScriptControl Tutorial from Microsoft.  From these two articles I was able to parse together what I needed to do. So off to the code:

So I have my user control (mine happened to be an admin add/edit page of a module) and I added the MediaContentSelectorView to the page.

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="FeaturedMessagesAddEditView.ascx.cs" Inherits="CorpComWeb.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView"  %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sitefinity" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Modules.Libraries.Web.UI.Designers" TagPrefix="sf1" %>
  
<telerik:RadScriptManager ID="manager" runat="server"></telerik:RadScriptManager>
<!-- Need this to prevent javascript error "DateCreated.sitefinityLocaleFormat is not a function" -->
<sitefinity:UserPreferences ID="userPreferences" runat="server" />
<div class="sfMain sfClearfix">
    <div class="sfContent">
        <div class="rgTopOffset sfWorkArea">
            <div class="sfFormIn">
                <sf1:MediaContentSelectorView id="selectorView" runat="server" 
                    ContentType="Telerik.Sitefinity.Libraries.Model.Image"
                    ParentType="Telerik.Sitefinity.Libraries.Model.Album"
                    LibraryBinderServiceUrl="~/Sitefinity/Services/Content/AlbumService.svc/"
                    MediaContentBinderServiceUrl="~/Sitefinity/Services/Content/ImageService.svc/"
                    MediaContentItemsListDescriptionTemplate="Telerik.Sitefinity.Resources.Templates.Designers.Libraries.Images.ImageItemDescriptionTemplate.htm"
                    DisplayResizingOptionsControl="false"
                    ShowOpenOriginalSizeCheckBox="false">
                </sf1:MediaContentSelectorView> <br />
                     <asp:HiddenField ID="imageId" runat="server" ClientIDMode="Static" />
                <p><asp:Button ID="btnSave" runat="server" Text="Save" onclick="btnSave_Click" /></p>
            </div>
        </div>
    </div>
</div>

So the above is pretty easy right?  This is a stripped down user control just to get idea across.  All of the registered assemblys are required as far as I know.  The hidden field is used to store the ID of the image that is selected in the MediaContentSelectorView.

Next is the code behind and this is where it starts getting difficult:
UserControl.ascx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Telerik.Sitefinity;
using Telerik.Sitefinity.Data;
using Telerik.Sitefinity.Model;
using Telerik.Sitefinity.Modules;
using Telerik.Sitefinity.Libraries;
using Telerik.Sitefinity.Libraries.Model;
using Telerik.Sitefinity.Modules.Libraries;
using Telerik.Sitefinity.Modules.Libraries.Images;
using Telerik.Sitefinity.Modules.Pages;
using Telerik.Sitefinity.Modules.Pages.Web.UI;
using Telerik.Sitefinity.Taxonomies;
using Telerik.Sitefinity.Taxonomies.Model;
using Telerik.Sitefinity.Web;
using Telerik.Sitefinity.Web.UI.ControlDesign;
using Telerik.Sitefinity.Web.UI.Fields;
using Telerik.Sitefinity.Resources;
using Telerik.Web.UI;
  
namespace Sample
    public partial class ImageSelector: System.Web.UI.UserControl, IScriptControl
    
        private ScriptManager sm;
        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        
              
        
  
        //This is needed to verify a scriptmanager is on the page.  I used a RadScriptManager but you can probably use others.
        protected override void OnPreRender(EventArgs e)
        
            if (!this.DesignMode)
            
                // Test for ScriptManager and register if it exists
                sm = RadScriptManager.GetCurrent(this.Page);
  
                if (sm == null)
                    throw new HttpException("A ScriptManager control must exist on the current page.");
  
                sm.RegisterScriptControl(this);
            
  
            base.OnPreRender(e);
        
  
    //This is probably required, I found this from the code from the microsoft site.  Experiment it might not be required.
        protected override void Render(HtmlTextWriter writer)
        
            if (!this.DesignMode)
                sm.RegisterScriptDescriptors(this);
  
            base.Render(writer);
        
  
    //Must be implemented to use the IScriptControl interface.
        protected virtual IEnumerable<ScriptReference> GetScriptReferences()
        
        //This is where you load the javascript file just like you would in a javascript control.
            ScriptReference imageReference = new ScriptReference();
            imageReference.Path = "~/Modules/FeaturedMessages/Admin/JavaScript/FeaturedMessagesAddEditView.js";
  
            return new ScriptReference[] imageReference ;
        
  
        //Must be implemented to use the IScriptControl interface.
        protected virtual IEnumerable<ScriptDescriptor> GetScriptDescriptors()
        
            //Must declare your control as the client.  Normaally you would put the custom control in here but instead you would put the client ID of your control
            ScriptControlDescriptor imageDescriptor = new ScriptControlDescriptor("CorpComWeb.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView", this.ClientID);
            //Send the MediaContentSelectorView clientside object to the page.
            imageDescriptor.AddComponentProperty("selectorView", selectorView.ClientID);
  
            return new ScriptDescriptor[] imageDescriptor ;
        
              
  
        IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
        
            return GetScriptReferences();
        
  
        IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
        
            return GetScriptDescriptors();
        
  
  
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        
             
        
  
        protected override void OnUnload(EventArgs e)
        
            base.OnUnload(e);
            if (context != null)
                context.Dispose();
        
    

The key to this code was to inherit from IScriptControl and implement the methods that it needs to fullfill its contract, which are the GetScriptDescripters and GetScriptReferences.

Finally, the Javascript File that will connect all of this together.  This is where things got really hairy for me as stuff that failed would through javascript messages.

Type.registerNamespace("Sample.ImageSelector");
  
Sample.ImageSelector = function (element)
   Sample.ImageSelector.initializeBase(this, [element]);
  
    this._imageId = null;
  
Sample.ImageSelector.prototype =
    initialize: function ()
        Sample.ImageSelector.callBaseMethod(this, 'initialize');
        this._itemSelectDelegate = Function.createDelegate(this, this._itemSelect);
        this._selectorView.add_onItemSelectCommand(this._itemSelectDelegate);
  
    ,
    dispose: function ()
        Sample.ImageSelector.callBaseMethod(this, 'dispose');
        if (this._selectorView)
            this._selectorView.add_onItemSelectCommand(this._itemSelectDelegate);
        
    ,
    get_selectorView: function ()
        return this._selectorView;
    ,
    set_selectorView: function (value)
        this._selectorView = value;
    ,
  
    _itemSelect: function (sender, args)
    //Get the date from the image.  I wanted the ID of the image.
        this._imageId = args.get_dataItem().Id;
    //Save this in a hidden field on the page.  This allows it to get passed back to the server.
        $("#imageId").val(this._imageId);
    ,
  
    add_onItemSelectCommand: function (delegate)
        this.get_events().addHandler('onItemSelectCommand', delegate);
    
  
CorpComWeb.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView.registerClass('CorpComWeb.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView', Sys.Component);
  
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

The biggest key here is the _itemSelect Method.  In this method is where the selected object stores the ID of the image to a hidden variable on the control.  This could be any property of the image however. 

*DISCLAIMER*  All the code above is stripped down portions of the control I wrote for my client and I am not able to give the entire source.  I will try to include a working piece for others to look at when I have time.  I do not guarantee that the above code will even work/compile.  My purpose for writing this guide was to help others have a "Eureka!" moment and they can apply this to there own work.

All in all I got this to work through sure diligence, any suggestions on how to better this would greatly be appreciated and I hope this will help others accomplish what they have been trying to do!

Posted by Community Admin on 28-Mar-2012 00:00

Hi Brett,

 Thank you very much for sharing your findings with the community. I am sure this can help a lot of people. I updated your Telerik points.

All the best,
Svetoslav Petsov
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

This thread is closed