`
yake2011
  • 浏览: 18976 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

How to work around bugs in the SPGridView control

 
阅读更多
原文链接

 

11 Mar 2009 8:11 PM

 

SharePoint has a little known web control called SPGridView. This control can give you a SharePoint list-like view of data from any data source you can bind to (from a database or other sources). It also has features to sort, filter and group the data in much the same way users can with SharePoint lists. For more information on how to use this, Paul Robinson has two great posts: SPGridView and SPMenuField: Displaying custom data through SharePoint lists Part 1 and Part 2. In addition, Robert Fridén has a good post on Filtering with SPGridView. However, there are two bugs that can be annoying and cause confusion to users:

  • When both filtering and grouping are enabled, the first group title row sometimes disappears.
  • When both sorting and filtering are enabled, the sort indicator arrow image will sometimes appear in the wrong column.

Working around either of these bugs requires you to create your own web control based on SPGridView and overriding the CreateChildControls method. Here is the full code listing for the solution to work around both bugs.

 

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.WebControls;

using Microsoft.SharePoint.WebControls;

namespace AdventuresInConsulting
{
    public class GridViewControl : SPGridView
    {
        protected override int CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
        {
            // Due to a bug in SPDataView, we need to reset the private field previousGroupFieldValue so the 
            // first grouping row title will consistently show up
            FieldInfo fieldInfo = typeof(SPGridView).GetField("previousGroupFieldValue",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            if (fieldInfo != null)
                fieldInfo.SetValue(this, null);

            int returnValue = base.CreateChildControls(dataSource, dataBinding);

            // Fix up a bug in the SPGridView where it is putting the sort arrow indicator on the wrong
            // column if AllowFiltering is true
            if (this.AllowFiltering && this.HeaderRow != null && !string.IsNullOrEmpty(this.SortExpression))
            {
                List<string> filterFields = new List<string>(this.FilterDataFields.Split(','));
                if (this.AllowGrouping) filterFields.Insert(0, string.Empty);

                for (int i = 0; i < this.HeaderRow.Cells.Count; i++)
                {
                    DataControlFieldHeaderCell cell = this.HeaderRow.Cells[i] as DataControlFieldHeaderCell;
                    if (cell != null)
                    {
                        // Find the sort image control
                        Image sortImage = null;
                        foreach (Control c in cell.Controls)
                        {
                            sortImage = c as Image;
                            if (sortImage != null && sortImage.ImageUrl == this.SortDirectionImageUrl)
                                break;
                        }

                        // If this field is filterable, make sure the menu image is correct
                        if (i < filterFields.Count && filterFields[i].Trim() != string.Empty)
                        {
                            // If there is also an image control, remove it (we'll add it back in the right place)
                            if (sortImage != null) cell.Controls.Remove(sortImage);

                            // Find the menu control and add or remove the image in there as needed
                            foreach (Control c in cell.Controls)
                            {
                                if (c is Microsoft.SharePoint.WebControls.Menu)
                                {
                                    Microsoft.SharePoint.WebControls.Menu menu = c as Microsoft.SharePoint.WebControls.Menu;
                                    if (this.SortExpression.Equals(this.Columns[i].SortExpression, StringComparison.InvariantCultureIgnoreCase))
                                    {
                                        // Make sure it has the sort indicator
                                        menu.RightImageUrl = this.SortDirectionImageUrl;
                                        menu.ImageTextSpacing = new Unit("2px", CultureInfo.InvariantCulture);
                                    }
                                    else if (menu.RightImageUrl == this.SortDirectionImageUrl)
                                    {
                                        // Make sure it doesn't have the sort indicator
                                        menu.RightImageUrl = null;
                                        menu.ImageTextSpacing = Unit.Empty;
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (this.SortExpression.Equals(this.Columns[i].SortExpression, StringComparison.InvariantCultureIgnoreCase))
                            {
                                // Make sure there is a sort image
                                if (sortImage == null)
                                {
                                    sortImage = new Image();
                                    sortImage.ImageUrl = this.SortDirectionImageUrl;
                                    sortImage.Style[HtmlTextWriterStyle.MarginLeft] = "2px";
                                    cell.Controls.Add(sortImage);
                                }
                            }
                            else if (sortImage != null)
                            {
                                // Remove the sort image if it exists
                                cell.Controls.Remove(sortImage);
                            }
                        }
                    }
                }
            }

            return returnValue;
        }
    }
}

 

 

Fixing the group title row disappearance

Making it so that the first group title row doesn't disappear is fairly simple. I noticed that this problem occurred if the filter or sort caused the first group in the new results to be the same as the last group from the previous results. This led me to look at how SPGridView was checking for the start of a new group. Sure enough, it was just checking to see if the value of the group field in the current row was different from the group field value the last time it detected a change. It saves the last group value in a field called previousGroupFieldValue. That value was being preserved between calls (presumably so that paging will work correctly). The easy fix is to reset the last group value. The problem was that the value was accessed through a private field. Of course, thanks to .NET reflection, we won't let that stand in our way. We just grab the FieldInfo for previousGroupFieldValue and then forcibly set the value.

NOTE: you may need to modify this slightly if paging is enabled. You probably only want to reset it if the page has not changed.

Fixing the sort indicator arrow image

Fixing the sort indicator arrow image is the more difficult of the two work arounds. I had hoped to recreate the CreateChildControls method of SPGridView and just avoid the image from coming up in the wrong place. However, it turns out that SPGridView calls its base class CreateChildControls method and there is no way in C# for a derived class to call its base's base class methods. So, rather than trying to recreate a whole chain of CreateChildControls methods, I just let SPGridView put the arrows where it wanted to and then fixed them up later.

The code loops through all of the column headers and looks for the sort indicator image either as a standalone Image control, or as the RightImageUrl of the column menu's title. We remove the image where it doesn't belong and add the image where it does belong.

Note on this bug: the issue arises because enabling grouping causes a hidden column to be added to the front of the grid and the code logic SPGridView uses to decide which column to put the filter indicator on is off by one. You'd think it'd be off to the left, but it is actually off to the right because whoever wrote the code knew there was a hidden column, but they overcompensated for it (kind of feels like being in a car with a kid learning to drive with power steering for the first time).

分享到:
评论

相关推荐

    What bugs in the cloud?

    在云计算系统中,存在着各种各样的问题和故障,这些被称为“云中的bug”。由于云计算在现代数据中心基础设施中扮演着核心角色,云系统的开发和部署问题的研究就显得尤为重要。该研究通过对六个流行的云系统(Hadoop ...

    前端MD5加密MD5.js

    * to work around bugs in some JS interpreters. * 需要加密的文字或者数字作为必要参数传入: hexMD5.hexMD5(参数); (Text or Numbers that need to be encrypted are passed in as necessary parameters: ...

    What bugs live in the cloud? A study of 3000+ issues in cloud system

    本研究深入分析了超过3000个云系统中的问题,对这些问题进行了细致的分类与研究,最终得出了与云系统相关的bugs种类、来源、以及它们对系统的影响。以下是对这份研究中涉及到的关键知识点的详细解析: 1. 云系统的...

    XL Report 4.123

    XL Report is a set of Delphi-components for report generation in Microsoft Excel by means ... We used variables of Variant data type only once or twice to work around some bugs in the Excel Type Library.

    How to find and fix faults in Linux applications

    Everybody claims that it is easy to find and fix bugs in programs written under Linux. Unfortunately it is very hard to find documents explaining how to do that. In this article you will learn how to ...

    discovRE__Efficient_Cross-Architecture_Identification_of_Bugs_in_Binary_Code.pdf

    discovRE: Efficient Cross-Architecture Identification of Bugs in Binary Code是发表在NDSS'16会议上的论文。本文在SP'15的基础上提出了在效率和效果上都有提高的跨架构二进制代码漏洞检测方案。 Abstract & ...

    Senfore_DragDrop_v4.1

    This is believed to be a bug in the Windows clipboard and a work around hasn't been found yet. * Asynchronous targets appears to be broken in the current release. * When TDropFileTarget....

    Specification by Example - How Successful Teams Deliver the Right Software

    2. **Higher Product Quality**: By using examples, developers and testers can create more accurate and reliable code, leading to fewer bugs and higher overall quality of the software product. ...

    A Few Billion Lines of Code Later - Using Static Analysis to Find Bugs in the Real World - ACM - 2010 (BLOC-coverity)-计算机科学

    66 communicAtions of the Acm | FeBrUAry 2010 | vOl. 53 | nO. 2contributed articlesIn 2 002, COVErITY commercialized3 a research static bug-finding tool.6,9 Not surprisingly, as academics, our view ...

    Xcode Treasures: Master the Tools to Design, Build, and Distribute Great Apps

    Find the tools that make the code editor pleasant to work with, even in long coding sessions. Discover the right way to find and fix bugs when you have lots of code that’s not always playing nicely ...

    The BUGS Book A Practical Introduction to Bayesian Analysis

    《The BUGS Book: A Practical Introduction to Bayesian Analysis》这本书是由BUGS软件的开发团队撰写的,旨在提供对BUGS程序及其使用的实践入门。该书全面涵盖了BUGS的所有功能,包括预测、缺失数据处理、模型批评...

    Open Drawing Alliance ActiveX Control

    Zoom to extents functionality is now working, which will allow you to create a drawing and then adjust the view so that the drawing opens in autocad zoomed to its current extents.&#61623; The Layer ...

    The Busy Coder's Guide to Android Development V8.12

    and moved the RecyclerView chapter to be earlier in the book • Added some material on the Chrome OS emulator • Moved the material on SlidingPaneLayout to the Widget Catalog • Made minor ...

    Manage Software Testing

    It is imperative to determine if bugs do exist and then be able to metric how quickly they can be identified, the cost they incur, and how many remain in the product when it is released. With this ...

    The BUGS Book: A Practical Introduction to Bayesian Analysis

    BUGS软件是全球最受欢迎的贝叶斯分析软件之一,本书《The BUGS Book: A Practical Introduction to Bayesian Analysis》由BUGS软件的开发团队编写,是一本实践性强的入门书籍,提供了对BUGS程序及其使用的实用介绍。...

    Effective Python Development for Biologists pdf

    Testing - learn how automated testing can make your code more reliable, how to catch bugs before they impact your work, and how to edit code with confidence. Performance - learn how to make your code ...

    Coding Games in Python

    Each chapter in Coding Games in Python shows how to construct a complete working game in simple numbered steps. The book teaches how to use freely available resources, such as PyGame Zero and Blender,...

    Intrusion Detection: Network Security beyond the Firewall

    Chapter 3—The Role of Access Control in Your Environment Configuration Problems Program Bugs What Is Access Control? How Are Access Control Decisions Made? Access Control Lists Who Are You? ...

    a project model for the FreeBSD Project.7z

    During the Core elections in 2002, Mark Murray stated “I am opposed to a long rule-book, as that satisfies lawyer-tendencies, and is counter to the technocentricity that the project so badly needs.”...

Global site tag (gtag.js) - Google Analytics