Using a User Control

This forum is only for questions or discussions about working with the mojoPortal source code in Visual Studio, obtaining the source code from the repository, developing custom features, etc. If your question is not along these lines this is not the right forum. Please try to post your question in the appropriate forum.

Please do not post questions about design, CSS, or skinning here. Use the Help With Skins Forum for those questions.

This forum is for discussing mojoPortal development

This forum is only for questions or discussions about working with the mojoPortal source code in Visual Studio, obtaining the source code from the repository, developing custom features, etc. If your question is not along these lines this is not the right forum. Please try to post your question in the appropriate forum.

You can monitor commits to the repository from this page. We also recommend developers to subscribe to email notifications in the developer forum as occasionally important things are announced.

Before posting questions here you might want to review the developer documentation.

Do not post questions about design, CSS, or skinning here. Use the Help With Skins Forum for those questions.
This thread is closed to new posts. You must sign in to post in the forums.
5/18/2009 6:55:32 PM
Gravatar
Total Posts 26

Using a User Control

Hello,

I have an existing Custom User Control that retreives information from an existing database. I'd like to use my existing User Control within the mojoPortal framework. How can I accomplish this?


BTW, while I have seen a feature called "HTML Fragment" that allows me to retrieve any .html fragment for display, I haven't seen an "ASCX Fragment" upload that correctly renders the server controls.


thank you for your time!
Michael

 

5/19/2009 4:52:30 AM
Gravatar
Total Posts 18439

Re: Using a User Control

Hi,

See this document to learn how to use a UserControl in mojoPortal http://www.mojoportal.com/hello-world-developer-quick-start.aspx

No, there is no such thing as an ascx fragment feature. A .ascx file is a UserControl, you can use UserControls inside UserControls, the outermost one is the one to plugin to mojoportal as a feature plugin.

Hope it helps,

Joe

5/19/2009 11:30:40 AM
Gravatar
Total Posts 26

Re: Using a User Control

Thank you Joe,

Yes, your answer is helpful.  I see now that "ASCX Fragment" Feature doesn't need to exist, because ASCX files can be added dynamically as Features.  The trick, is that they must be added via the Administration Menu first, before use.

 

SECOND QUESTION

Must all the Features (a.k.a. Site Modules) exist under the /Web folder only (aka mojoPortal.Web project)?  Is it possible for them to exist under a different project as to maintain not altering the exsisting mojoPortal code?

In your articles, you recommend that we keep all our custom work in separate projects and don't make changes to the existing mojoPortal code.  Isn't adding code the mojoPortal.Web project considered changing the existing mojoPortal code?  I like the example article that you rcomended to me, but isn't installing the Hello World examples changing the existing mojoPortal code?  Can I have your thoughts?

 

thank you,

Michael

5/21/2009 8:56:05 AM
Gravatar
Total Posts 18439

Re: Using a User Control

Hi Michael,

Ultimately at runtime the files need to be copied up into the main web in order to work. The hello world examples use inline code with no code behind and therefore no compiled dll. If using this approach its ok to put the files in a custom folder within the main web project, but I would not add them to the project itself, ie I would not include them in the mojoPortal.Web.csproj file. I don't generally use inline code in my own work, that is just the easiest way for new developers without much ASP.NET knowledge to get started so I did it that way on the hello world examples to make it easy for people to get started. It works by just dropping in the files nothing to compile so its easier and lowers the entry point barriers for new developers.

For more advanced developers I recommend you organise your projects the same way I do. If you download the mojoportal source code and study the solution structure you will see that all the features are in a set of projects separate from the core and you can structure your projects them same way.

Most of the features are in the mojoPortal.Features.UI, mojoPortal.Features.Business, and mojoPortal.Features.Data* projects. They all compile into dlls. The mojoPortal.Features.UI project is a web project but you never run it directly. It has post build events that copy its dlls and .aspx and .ascx and .resx files up to the correct locations under the main mojoPortal.Web (aka Web folder) project. If you right click the mojoPortal.Features.UI project node and choose Properties you can see how to make a post build event for your own projects.

You do need to be careful that your post build doesn't accidently overwrite needed files in mojoportal. So, yes you do add files on disk but not to the projects and be careful in naming of folders and files to avoid clashes with existing files and folders. There are some folders that you will name the same but not files. There are conventions for where to put files for Setup, Help, Message Tamplates, resource files etc. You can even use the installation and upgrade sysetm to run your install and upgrade scripts and configure you feature automatically instead of via Administration pages. Study how this is done for mojoPortal.Features.UI to learn where files should go.

The ideas is for your custom features to live in your own custom projects and get copied up to the main project the same way we do with existing features. You can study the code for existing features and get lots of useful fragments for your own features butbest to avoid making changes directly on mojoportal code and keep all your custom stuff in your own external projects. I recommend getting the mojoportal cod from svn trunk and you can do svn update, rebuild solution visit /Setup/Default.aspx to get up to date on the latest version at any time. Its also good to subscribe to svh commit notifications so you can get emails and see what changes are happening in mojoportal code.

Hope it helps,

Joe

5/21/2009 12:57:45 PM
Gravatar
Total Posts 26

Re: Using a User Control

 

Thank you Joe.  Yes, I see how the post-build events are the key to keeping code separate and allowing it to work at the same time. :)  I believe this information is only available in one of your 30 mins screencasts, rather than a text help article.

 

Joe said, "I recommend getting the mojoportal cod from svn trunk and you can do svn update, rebuild solution visit /Setup/Default.aspx to get up to date on the latest version at any time."

I understand this model.  However using TFS seems to make this model challenging, as (1) the model necessitates two source control systems -and- (2) TFS requires the solution to build and check-in code.

 

thanks,
Michael

5/21/2009 2:01:42 PM
Gravatar
Total Posts 18439

Re: Using a User Control

Hi Michael,

Yes it can be problematic working across different source code management tools and repositories. I really don't have any perfect answers to offer on it. I'm not very familiar with use of TFS (though I've worked with its predessor VSS a lot over the course of my career). Of course its easy for me since I use only svn. I have worked on custom development projects where the client had their own svn repository and I was able to keep their projects in a folder beneath my svn tree but outside of my svn and checkout and commit to their repository from that folder without isues with mojoportal svn at a parent folder. The custom .sln file lived in the root of my tree but outside of either repository's control. I periodically would throw a copy in a different folder in their tree just to have a copy but I worked with the .sln outside of source control.

I don't know if similar strategies are possible with TFS. I also don't know if its possible or what will be involved for you to make automatic builds work. I mean if it builds by the .sln file it should build correctly but the the deployment of a build may have issues. The VS Publish feature for example doesn't work correctly with our solution because it only packages files that are members of the mojoPortal.Web.csproj file, so it misses all the mojoPortal.Features stuff that was copied by post build events. Maybe there are ways around this issue with msbuild configuration I just don't know enough about it. Anything you learn about this in your work with it please share.

You can always periosdically checkout our svn trunk into a separate folder and then right click and use SVN Export to export thefiles to a new folder then paste them into your TFS tree. This will make sure you have the newest files but won't handle files that should be removed and you would have to be able to add the new files to your TFS.

Best,

Joe

11/12/2010 12:18:53 PM
Gravatar
Total Posts 13

Re: Using a User Control

I have a user control with two dropdown lists to choose an area which lists the locations, when I use in my project works fine but to integrate this

logic with mojoPortal I have unexpected results. I'll explain with an example, I have 3 items on the list area and choose an item from the list is

generated by charging returning in the Zone list now 6 elements and if I click on any item will now carry 9 items, this should not work that way

because the only thing that should change with the user interaction should be the list of locations, I have put break points in the Selected Index

Changed event but rather than choose one or the other item ignores the breaking point so I assume that no run the scheduled events are:

CodeBehind:
        protected void ddlZone_SelectedIndexChanged(object sender, EventArgs e)
        {
            ddlLocation.Items.Clear();
            ddlLocation.Items.Insert(0, new ListItem("[Select]", "0"));
        }

        protected void ddlLocation_SelectedIndexChanged(object sender, EventArgs e)
        {
            UTPID = Convert.ToInt32(ddlUTP.SelectedValue);
        }

Desing:
    <asp:DropDownList ID="ddlZone" runat="server" AutoPostBack="True" AppendDataBoundItems="true"
            DataSourceID="SqlDataSourceZone" DataTextField="Zone" DataValueField="ZoneID"
                Font-Size="Small" onselectedindexchanged="ddlZone_SelectedIndexChanged"
                Width="200px">
                <asp:ListItem Value="0">[Select]</asp:ListItem>
    </asp:DropDownList>
        <asp:SqlDataSource ID="SqlDataSourceZone" runat="server"
                ConnectionString="<%$ ConnectionStrings:UserConnectionString %>"
                SelectCommand="SELECT ZoneID, Zone FROM Zone">
    </asp:SqlDataSource>

    <asp:DropDownList ID="ddlLocation" runat="server" AppendDataBoundItems="true"
            DataSourceID="SqlDataSourceLocation" DataTextField="Location" DataValueField="LocationID"
                Font-Size="Small" Width="200px"
                onselectedindexchanged="ddlLocation_SelectedIndexChanged">
                <asp:ListItem Value="0">[Select]</asp:ListItem>
        </asp:DropDownList>
        <asp:SqlDataSource ID="SqlDataSourceLocation" runat="server"
                ConnectionString="<%$ ConnectionStrings:UserConnectionString %>"
                SelectCommand="SELECT * FROM [Location] WHERE ([ZoneID] = @ZoneID)">
                <SelectParameters>
                <asp:ControlParameter ControlID="ddlZone" Name="ZoneID"
                PropertyName="SelectedValue" Type="Int32" />
                </SelectParameters>
    </asp:SqlDataSource>

The two combo boxes are connected to their respective tables (Area and Location) by using data sources where SQLDataSourceLocation obtains the ID from

the ddlZone (linked to the SQLDataSourceZone) and load the information in the ddlLocations.

Treat yourself to come up with any explanation I have placed a breakpoint in page load and is where you run the following classes:

WebAgendaModule.ascx.cs    (My user control)
ClueTipHelpLink.cs
AdminMenuLink.cs
FileManagerLink.cs
NewPageLink.cs
PageEditFeatures.cs
PageEditSettingLink.cs
WoopraScript.ascx.cs
TreeViewAdapter.cs
WebAgendaModule.ascx.cs    (My user control)
TreeViewAdapter.cs
mojoBasePage.cs
StyleSheetCombiner.ascx.cs
Metacontent.ascx.cs
ScriptLoader.cs
AnalyticsAsyncTopScript.cs
WatermarkTextBox.cs
mojoPanel.cs
ModuleTitleControl.cs
ClueTipHelpLink.cs
mojoPanel.cs
TreeViewAdaptar.cs
mojoSiteMapPath.cs
mojoBasePage.cs

Please I need help.

Regards,

Hector.

 

11/13/2010 9:55:06 AM
Gravatar
Total Posts 44

Re: Using a User Control

Hi Hector,
This is a proof of concept, not a recommended way of working with mojoPortal, you should follow the guest book example and use an independent project for your controls, anyway, this is what I did as a test for a linked drop down control;

1. Create a control, LinkedDropdown.ascx in the mojoPortal controls directory;

ASCX

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="LinkedDropdown.ascx.cs" Inherits="mojoPortal.Web.Controls.LinkedDropdown" %>

<table><tr><td><asp:DropDownList ID="ddlListAreas" runat="server"
onselectedindexchanged="ddlListAreas_SelectedIndexChanged" AutoPostBack="true">
</asp:DropDownList></td><td><asp:DropDownList ID="ddlListZones" runat="server"
onselectedindexchanged="ddlListZones_SelectedIndexChanged" AutoPostBack="true">
</asp:DropDownList></td></tr>
<tr><td>Selected Zone:</td><td><asp:TextBox ID="txtZone" runat="server"></asp:TextBox></td></tr>
</table>

CODE BEHIND
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace mojoPortal.Web.Controls
{
    public partial class LinkedDropdown : System.Web.UI.UserControl
    {
        List<ListItem> Areas;
        List<string> Zones;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                //Initialise Areas
                Areas = new List<ListItem>();
                Areas.Add(new ListItem("Select Area", "0"));
                Areas.Add(new ListItem("Area1", "1"));
                Areas.Add(new ListItem("Area2", "2"));
                Areas.Add(new ListItem("Area3", "3"));
                Areas.Add(new ListItem("Area4", "4"));
                //Populate Drop Lists
                this.ddlListAreas.DataSource = Areas;
                this.ddlListAreas.DataValueField = "Value";
                this.ddlListAreas.DataTextField = "Text";
                this.ddlListAreas.DataBind();
            }
        }

        protected void ddlListAreas_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.txtZone.Text = "";
            string selectedArea = this.ddlListAreas.SelectedItem.ToString();
            PopulateZones(selectedArea);

        }

        void PopulateZones(string area)
        {
            //Initialise Zones - cache this
            Zones = new List<string>();
            Zones.Add("Area1Zone1");
            Zones.Add("Area1Zone2");
            Zones.Add("Area1Zone3");
            Zones.Add("Area2Zone1");
            Zones.Add("Area2Zone2");
            Zones.Add("Area2Zone3");
            Zones.Add("Area3Zone1");
            Zones.Add("Area3Zone2");
            Zones.Add("Area3Zone3");
            Zones.Add("Area4Zone1");
            Zones.Add("Area4Zone2");
            Zones.Add("Area4Zone3");

            IEnumerable<string> zList = from a in Zones where a.Substring(0, 5).Equals(area) select a;
            ListItem lstItm = null;
            int zCount = zList.Count();
            //Clear exisitng list items
            this.ddlListZones.Items.Clear();
            if (zCount > 0)
            {
                this.ddlListZones.Items.Add(new ListItem("Select Zone", "0"));
            }
            else
            {
                this.ddlListZones.Items.Add(new ListItem("No Zones Found", "0"));
                return;
            }
            for (int i = 0; i < zCount; i++)
            {
                lstItm = new ListItem(zList.ElementAt(i), i.ToString());
                this.ddlListZones.Items.Add(lstItm);
            }
        }


        protected void ddlListZones_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.txtZone.Text = this.ddlListZones.SelectedItem.Text;
        }
    }
}

WEB.CONFIG <controls>
<add tagPrefix="lnkddl" tagName="LinkedDropdown" src="~/Controls/LinkedDropdown.ascx"/>

In my copy of layout.master in my skin directory I added;
<lnkddl:LinkedDropdown id="lnkddl1" runat="server"></lnkddl:LinkedDropdown>

to the panel id="divCenter"

Your code will differ because you are using a data source, but the principal is the same.

Best Regards,

Vince.

 


 

11/19/2010 2:53:36 AM
Gravatar
Total Posts 13

Re: Using a User Control

Estimado, me he guiado de un control de usuario ubicado en la carpeta "mojoPortal.Web/Admin/AdminTaxRate" pero el problema es que cuando elijo algun item de cualquiera de las listas, estas se limpian completamente ¿Que puede estar pasando? mi codigo es el siguiente:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Configuration;
using System.Globalization;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using mojoPortal.Web;
using mojoPortal.Web.Framework;
using mojoPortal.Web.UI;
using log4net;
using WebAgenda.Business;
using Resources;

namespace WebAgenda.UI
{

    public partial class ReservaModule : SiteModuleControl
    {
        // FeatureGuid 410fbd96-50be-4724-9001-b61a5505eeb0
        private Guid ZonaID = new Guid("410FBD96-50BE-4724-9001-B61A5505EEA2");
        private Guid UTPID = Guid.Empty;
        private DateTime Fecha;

        #region OnInit

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            this.Load += new EventHandler(Page_Load);
            ddlZona.SelectedIndexChanged += new EventHandler(ddlZona_SelectedIndexChanged);
            ddlUTP.SelectedIndexChanged += new EventHandler(ddlUTP_SelectedIndexChanged);
            CalendarAgenda.SelectionChanged += new EventHandler(CalendarAgenda_SelectionChanged);
        }

        #endregion

        void CalendarAgenda_SelectionChanged(object sender, EventArgs e)
        {
            BindGrid();
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            LoadSettings();
            PopulateLabels();
            PopulateControls();
        }

        private void PopulateControls()
        {
            TitleControl.EditUrl = SiteRoot + "/ReservaModule/ReservaModuleEdit.aspx";
            TitleControl.Visible = !this.RenderInWebPartMode;
            if (this.ModuleConfiguration != null)
            {
                this.Title = this.ModuleConfiguration.ModuleTitle;
                this.Description = this.ModuleConfiguration.FeatureName;
            }

            if (Page.IsPostBack) return;

            BindZonaList();
            BindUTPList();

            if ((UTPID == Guid.Empty) && (ddlUTP.SelectedValue.Length == 36))
            {
                UTPID = new Guid(ddlUTP.SelectedValue);
            }

            Fecha = System.DateTime.Now;
            BindGrid();
        }

        private void PopulateLabels()
        {
            TitleControl.EditText = "Edit";
        }

        private void LoadSettings()
        {

        }

        private void BindZonaList()
        {
            DataTable datatable = Zona.GetList();
            ddlZona.DataSource = datatable;
            ddlZona.DataBind();
            if ((!Page.IsPostBack) && (ZonaID != Guid.Empty))
            {
                ListItem listitem = ddlZona.Items.FindByValue(ZonaID.ToString());
                if (listitem != null)
                {
                    ddlZona.ClearSelection();
                    listitem.Selected = true;
                }
            }
        }

        private void BindUTPList()
        {
            if (ddlZona.SelectedIndex > -1)
            {
                ZonaID = new Guid(ddlZona.SelectedValue);
                using (IDataReader reader = UTP.GetByZonaID(ZonaID))
                {
                    ddlUTP.DataSource = reader;
                    ddlUTP.DataBind();
                }
            }
            ListItem listitem = ddlUTP.Items.FindByValue(UTPID.ToString());
            if (listitem != null)
            {
                ddlUTP.ClearSelection();
                listitem.Selected = true;
            }
            else
            {
                listitem = ddlUTP.Items.FindByValue(UTPID.ToString().ToUpper());
                if (listitem != null)
                {
                    ddlUTP.ClearSelection();
                    listitem.Selected = true;
                }
            }
        }

        void ddlUTP_SelectedIndexChanged(object sender, EventArgs e)
        {
            UTPID = new Guid(ddlUTP.SelectedValue);
            if (ddlZona.SelectedIndex > -1)
            {
                ZonaID = new Guid(ddlZona.SelectedValue);
            }
            BindGrid();
        }

        void ddlZona_SelectedIndexChanged(object sender, EventArgs e)
        {
            ZonaID = new Guid(ddlZona.SelectedValue);
            UTPID = Guid.Empty;
            BindUTPList();
            BindGrid();
        }

        private void BindGrid()
        {
            Fecha = CalendarAgenda.SelectedDate;
            UTPID = new Guid(ddlUTP.SelectedValue);
            DataTable dt = AgendaWeb.GetByUTPIDFecha(UTPID, Fecha);
            DataView dv = dt.DefaultView;
            GVDetails.DataSource = dv;
            GVDetails.DataBind();
        }
    }
}

He probado este mismo condigo en una pagina independiente que no herede de "SiteModuleControl" y funciona perfectamente... por lo que sospecho que debe haber algun codigo que cause conflicto con el mio pero al manejar tantas clases se me hace imposible hacer el seguimiento modulo por modulo. Por favor si alguien tiene idea de que puede estar pasando estaria muy agradecido.

Saludos,

Hector.

11/19/2010 3:44:17 AM
Gravatar
Total Posts 13

Re: Using a User Control

He puesto dos puntos de quiebre para los eventos:

ddlUTP_SelectedIndexChanged
ddlZona_SelectedIndexChanged

Y nunca se llegan a ejecutar por mas que selecciono un elemento de cualquiera de las listas ademas de tener definido los delegados en "OnInit"

            ddlZona.SelectedIndexChanged += new EventHandler(ddlZona_SelectedIndexChanged);
            ddlUTP.SelectedIndexChanged += new EventHandler(ddlUTP_SelectedIndexChanged);

Alguna idea de lo que pueda estar pasando?

11/19/2010 7:18:16 AM
Gravatar
Total Posts 13

Re: Using a User Control

La solucion fue agregar al Page Load "Page.EnableViewState = true" quedando asi:

        protected void Page_Load(object sender, EventArgs e)
        {
            LoadSettings();
            PopulateLabels();
            PopulateControls();
            Page.EnableViewState = true;
        }

Joe lo explica en otro hilo pero es asi de simple, una solucion algo marrana pero funciona.

Saludos,

Hector.

You must sign in to post in the forums. This thread is closed to new posts.