/// <summary>
        /// Process user-initiated sort operation
        /// </summary>
        /// <history>
        ///     [msellers]	5/17/2007	 Added
        /// </history>
        protected void grdDocuments_Sorting(object sender, GridViewSortEventArgs e)
        {
            var objCustomSortList      = new ArrayList();
            var objCustomSortColumn    = new DocumentsSortColumnInfo();
            var objCustomSortDirecton  = Models.SortDirection.Ascending;
            var strSortDirectionString = "ASC";

            // Set the sort column name
            objCustomSortColumn.ColumnName = e.SortExpression;

            // Determine if we need to reverse the sort.  This is needed if an existing sort on the same column existed that was desc
            if (ViewState ["CurrentSortOrder"] != null && ViewState ["CurrentSortOrder"].ToString() != string.Empty)
            {
                var existingSort = ViewState ["CurrentSortOrder"].ToString();
                if (existingSort.StartsWith(e.SortExpression, StringComparison.InvariantCulture) &&
                    existingSort.EndsWith("ASC", StringComparison.InvariantCulture))
                {
                    objCustomSortDirecton  = Models.SortDirection.Descending;
                    strSortDirectionString = "DESC";
                }
            }

            // Set the sort
            objCustomSortColumn.Direction = objCustomSortDirecton;
            objCustomSortList.Add(objCustomSortColumn);

            var docComparer = new DocumentViewModelComparer(objCustomSortList);

            Documents.Sort(docComparer.Compare);
            grdDocuments.DataSource = Documents;
            grdDocuments.DataBind();

            // Save the sort to viewstate
            ViewState ["CurrentSortOrder"] = e.SortExpression + " " + strSortDirectionString;
        }
        /// <summary>
        /// If the datagrid was not sorted and bound via the "_Sort" method it will be bound at this time using
        /// default values
        /// </summary>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            // only bind if not a user selected sort
            if (_documents == null)
            {
                // use DocumentComparer to do sort based on the default sort order
                var docComparer = new DocumentViewModelComparer(Settings.GetSortColumnList());
                Documents.Sort(docComparer.Compare);

                grdDocuments.DataSource = Documents;
                grdDocuments.DataBind();
            }

            Localization.LocalizeGridView(ref grdDocuments, LocalResourceFile);
        }
        List <DocumentViewModel> LoadDocuments()
        {
            var isAdmin   = UserInfo.IsSuperUser || UserInfo.IsInRole("Administrators");
            var cacheKey  = ModuleSynchronizer.GetDataCacheKey(ModuleId, TabModuleId);
            var documents = DataCache.GetCachedData <IEnumerable <DocumentViewModel> > (
                new CacheItemArgs(cacheKey, 1200, CacheItemPriority.Normal),
                c => LoadDocuments_Internal()
                );

            // remove unpublished and inaccessible documents from the list
            // TODO: Add test to check filtering logic
            var filteredDocuments = documents
                                    .Where(d =>
                                           (IsEditable || d.IsPublished(HttpContext.Current.Timestamp)) &&
                                           (isAdmin || CanView(d.Url)))
                                    .ToList();

            // sort documents
            var docComparer = new DocumentViewModelComparer(Settings.GetSortColumnList());

            filteredDocuments.Sort(docComparer.Compare);

            return(filteredDocuments);
        }