Silverlight Dashboard

A DotNetNuke module that displays a Silverlight Gauge that automatically updates every 30 seconds. The Silverlight application communicates with the DotNetNuke website using web services that cache the data so that the query is run only once every 30 seconds (no matter how many clients are consuming the data feed).

The Gauge

The gauge is a Silverlight application that is launched in a DotNetNuke module. The module allows a user to set a "Maximum Value" and a "Current Value". The "Maximum Value" is used to determine the maximum point on the gauge and the 4 other points between 0 and the maximum number. The "Current Value" is used to determine where the red dial will point to.

The settings in the DotNetNuke module allow the administrator to set the Dashboard Key key that is needed to call the web service (a random key is created automatically when the module is installed) and the Cache Time (the time that determines how often the query will run in the web service that provides the "Maximum Value" and a "Current Value" to the Silverlight application that displays the gauge).

When it is installed, the DotNetNuke module has files that reside in the App_Code directory and the DesktopModules directory. The gauge is contained in the Dashboard.xap file and launched by code in the View.ascx and View.ascx.cs files.

The following code is used to launch the Silverlight Dashboard.xap and pass to it, values including the password to call the web service and the address of the web service:

        protected void Page_Load(object sender, EventArgs e)
        {
            // Make sure Ajax is registered
            if (DotNetNuke.Framework.AJAX.IsInstalled())
            {
                DotNetNuke.Framework.AJAX.RegisterScriptManager();
            }

            if (!Page.IsPostBack)
            {
                string DashboardKey = "";
                // Get the current values
                DashboardDALDataContext DashboardDALDataContext = new DashboardDALDataContext();
                var DashboardDataResults = (from DashboardData in 
                                                DashboardDALDataContext.ADefWebserver_DashboardDatas
                                            select DashboardData).FirstOrDefault();

                txtMaxValue.Text = DashboardDataResults.DataMaxValue.ToString();
                txtCurrentValue.Text = DashboardDataResults.DataCurrentValue.ToString();

                var DashboardResults = (from Dashboard in DashboardDALDataContext.ADefWebserver_Dashboards
                                        select Dashboard).FirstOrDefault();

                DashboardKey = DashboardResults.DashboardKey.Trim();
                if (DashboardKey == "")
                {
                    // If Dashboard key is empty create one
                    // Note: This password is shared among all users so do not use for updating data. 
                    // See http://SilverlightDesktop.net for user specific password examples.
                    DashboardKey = Utility.GetRandomPassword();
                    DashboardResults.DashboardKey = DashboardKey;
                    DashboardDALDataContext.SubmitChanges();
                }

                // Launch Silverlight Dashboard
                string strWebServiceBase = GetWebServiceBase();
                SilverlightDashboard.InitParameters =
                    String.Format("Password={0},WebServiceBase={1}", DashboardKey, strWebServiceBase);
            }

            // Get an instance of the progress bar image
            Image imgProgress = (Image)AjaxUpdateProgress.FindControl("imgProgress");
            // Set the URL for the progress bar image
            imgProgress.ImageUrl = this.TemplateSourceDirectory + "/images/progressbar.gif";
        }

The gauge communicates with the DotNetNuke site through the Webservice.asmx web service entry point. The source code for the Dashboard.xap is contained in the Dashboard Silverlight project.

The Dashboard Silverlight Project

The Silverlight project receives variables passed from the DotNetNuke module in the Application_Startup method in the App.xaml.cs file.

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            // Load the main control
            this.RootVisual = new Page(e.InitParams["Password"], e.InitParams["WebServiceBase"]);
        }
It passes these values to the Page.xaml.cs file that sets up a "loop" to call the RefreshIteration method that will call the web service in the DotNetNuke site every 30 seconds to get the data for the gauge.
            DispatcherTimer dt = new DispatcherTimer();
            dt.Interval = new TimeSpan(0, 0, 0, intRefreshInterval, 0);
            dt.Tick += new EventHandler(RefreshIteration);
            dt.Start();
This method calls additional methods to retrieve the data and update the gauge.
        #region RefreshIteration
        private void RefreshIteration(object sender, EventArgs e)
        {
            BasicHttpBinding bind = new BasicHttpBinding();
            EndpointAddress MyEndpointAddress = new EndpointAddress(strWebServiceBase + "Webservice.asmx");
            var proxy = new WebServiceSoapClient(bind, MyEndpointAddress);

            proxy.GetDashboardDataCompleted += new EventHandler<GetDashboardDataCompletedEventArgs>(proxy_GetDashboardDataCompleted);
            proxy.GetDashboardDataAsync(strPassword);
        } 
        #endregion

        #region proxy_GetDashboardDataCompleted
        void proxy_GetDashboardDataCompleted(object sender, GetDashboardDataCompletedEventArgs e)
        {
            DashboardData objDashboardData = (DashboardData)e.Result;
            DisplayDashboardData(objDashboardData);
        } 
        #endregion

        #region DisplayDashboardData
        private void DisplayDashboardData(DashboardData objDashboardData)
        {
            double dCurrentValue = objDashboardData.CurrentValue;
            double dMaxValue = objDashboardData.MaxValue;
            double dPercentage = (dCurrentValue / dMaxValue) * 100;
            double dFinalValue = dPercentage * 3;
            PariesGauge.animateTheGauge.To = dFinalValue;
            PariesGauge.AnimateGauge.Begin();

            // Set Label values
            Double Txt_20 = (dMaxValue * 20d) / 100;
            Double Txt_40 = (dMaxValue * 40d) / 100;
            Double Txt_60 = (dMaxValue * 60d) / 100;
            Double Txt_80 = (dMaxValue * 80d) / 100;
            Double Txt_100 = dMaxValue;

            PariesGauge.Txt_20.Text = Convert.ToInt32(Txt_20).ToString();
            PariesGauge.Txt_40.Text = Convert.ToInt32(Txt_40).ToString();
            PariesGauge.Txt_60.Text = Convert.ToInt32(Txt_60).ToString();
            PariesGauge.Txt_80.Text = Convert.ToInt32(Txt_80).ToString();
            PariesGauge.Txt_100.Text = Convert.ToInt32(Txt_100).ToString();
        } 
        #endregion

The web service

The web service code resides in the App_Code of the DotNetNuke module in the WebService.cs file. Caching is used to prevent the database from being called more often than the current setting in the DotNetNuke module settings.

        #region GetDashboardData
        [WebMethod]
        public DashboardData GetDashboardData(string strPassword)
        {
            string objPassword = HttpContext.Current.Cache.Get("AdefWebserver_Dashboard_Password") as String;
            if (objPassword == null)
            {
                string sPassword = "";
                // The Dashboard password does not exist or has expired
                DateTime dtTimeToExpire = DateTime.MinValue;
                // Get the Dashboard password
                DashboardDALDataContext DashboardDALDataContext = new DashboardDALDataContext();
                var results = (from Dashboards in DashboardDALDataContext.ADefWebserver_Dashboards
                               select Dashboards).FirstOrDefault();

                sPassword = results.DashboardKey;
                //Get the time to expire the cached data
                dtTimeToExpire = GetDashboardDataExpireTime();
                HttpContext.Current.Cache.Insert("AdefWebserver_Dashboard_Password", sPassword, null, dtTimeToExpire, Cache.NoSlidingExpiration);
            }
            else
            {
                // There is a password so check access
                if (strPassword != objPassword)
                {
                    // That password was not valid so return an empty result
                    DashboardData objEmptyDashboardData = new DashboardData();
                    objEmptyDashboardData.CurrentValue = 0;
                    objEmptyDashboardData.MaxValue = 100;
                    return objEmptyDashboardData;
                }
            }

            DashboardData objDashboardData = HttpContext.Current.Cache.Get("AdefWebserver_Dashboard") as DashboardData;
            if (objDashboardData == null)
            {
                // The Dashboard data does not exist or has expired
                DateTime dtTimeToExpire = DateTime.MinValue;
                // Get the Dashboard data
                objDashboardData = GetDashboardDataFromDatabase();
                //Get the time to expire the cached data
                dtTimeToExpire = GetDashboardDataExpireTime();
                HttpContext.Current.Cache.Insert("AdefWebserver_Dashboard", objDashboardData, null, dtTimeToExpire, Cache.NoSlidingExpiration);
            }
            return objDashboardData;
        }
        #endregion

How to make it go faster

The default settings are set to update the gauge every 30 seconds. To make the update faster alter the setting in the DotNetNuke module settings and alter the intRefreshInterval variable in the Page.xaml.cs file in the Silverlight project (and recompile the project and deploy the Dashboard.xap file in the DotNetNuke module).

    public partial class Page : UserControl
    {
        // Change this value to refesh the client faster or slower
        int intRefreshInterval = 30; // in seconds

Jeff Paries - Creator of the Gauge

This project is another in a series of projects in collaboration with Jeff Paries. This project started with a post he made: "Silverlight Gauge Graphic" where he offered: "In case anybody needs it, here's a Silverlight/XAML gauge object".

Other projects with Jeff include:

Jeff Paries has a book on Silverlight called "Foundation Silverlight 2 Animation".

Back To:

Also see:


                        Dynamically loading Silverlight controls into resizable draggable windows.