This is a migrated thread and some comments may be shown as answers.

SortDescriptors.Expression column names not 'escaped' properly

3 Answers 169 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Micah
Top achievements
Rank 1
Micah asked on 14 Nov 2012, 07:22 PM
When I retrieve a SortDescriptors.Expression from my RadGridView the column names are not escaped when they have a space in the name. The FilterDescriptors.Expression does this correctly (IMO) or at least returns what I expect.

For example, I have a RadGridView bound to a DataTable with the following columns: ID, Unit ID, Name
I have the grid sorted by the column 'Unit ID' and also filtered to include only records where 'Unit ID'=1 at run-time.
I then run the following commands:
string sort = this.myRadGridView.SortDescriptors.Expression;
Console.WriteLine(sort);
 
string filter = this.myRadGridView.FilterDescriptors.Expression;
Console.WriteLine(filter);

I get the following output:
Unit ID ASC
([Unit ID] = 1)

With the FilterDescriptors.Expression value I can insert that string directly  back into a SQL query with no issues. With the SortDescriptors.Expression I have to run an addional routine on the result before I can use it in a query.

I have a workaround I am using right now (simple string replace) but the inconsistant results were something I thought I should bring up here. Maybe the SortDescriptors could be changed to work more like the FilterDescriptors in the future? Anyway, this post is mainly an 'FYI' but if anyone has any comments or tips, they would be appreciated.

3 Answers, 1 is accepted

Sort by
0
Emanuel Varga
Top achievements
Rank 1
answered on 15 Nov 2012, 09:24 AM
Hello Micah,

The difference you are talking about comes from the fact that for filters you have operators and values / custom filtering, and for sorting you do not have these, but you should not be using this if you need to get the fields on which you are sorting / filtering.

You can get the right fields and other info from the SortDescriptors / FilterDescriptors, by doing the following:
var sortDescriptors = grid.SortDescriptors;
foreach (var sortDescriptor in sortDescriptors)
{
    var propertyName = sortDescriptor.PropertyName;
    var sortDirection = sortDescriptor.Direction;
}
var filterDescriptors = grid.FilterDescriptors;
foreach (var filterDescriptor in filterDescriptors)
{
    var propertyName = filterDescriptor.PropertyName;
    var filterOperator = filterDescriptor.Operator;
    var expression = filterDescriptor.Expression;
    var filterValue = filterDescriptor.Value;
}

Hope this helps, If you have any other questions, please let me know.

Best Regards,
Emanuel Varga
WinForms MVP
0
Micah
Top achievements
Rank 1
answered on 15 Nov 2012, 04:50 PM
I like that method for building a sorting expression; it will probably be faster than my regex replace.  I assume this is how the Expression field is built behind the scenes and was trying to get away without "re-inventing the wheel" so to speak.

I still wonder about the inconsistancy of the results between the two descriptors. I don't use any custom filtering as you say (or as I understand it.) My grid starts initially with no sorting or filtering of any kind. Simply, To sort I click on the column headers and use the default sorting. For filters I click on the filter icon and click on the items I want.

grid.EnableCustomFiltering = False;
grid.EnableCustomSorting = False;
grid.EnableFiltering = True;
grid.EnableSorting = True;
grid.ShowHeaderCellButtons = True;
grid.ShowFilteringRow = False;

Additionally, using the filter and sorting mentioned in my first post, both SortDescriptor.PropertyName and FilterDescriptor.PropertyName return the value "Unit ID". Yet, when they are built into an expression, only the filter descriptor adds the brackets around the property name.

So while I understand it might be more beneficial to build my own sorting and filtering expressions from the descriptors, I then wonder why even have the Expression property on the collections if they are unusable in a practical manner?  I think this may be something that could be looked at in a future version of the library.
0
Julian Benkov
Telerik team
answered on 20 Nov 2012, 12:33 PM
Hi Micah,

The FilterDescriptors internally use an expression parser with escape functionality to support special symbols when building and executing filtering operations. The SortDescriptors use only simple method to parse and return expression string. Here is a code snippet used in the Expression property of SortDescriptorCollection:
public static List<SortDescriptor> ParseSortString(string sortString)
{
    List<SortDescriptor> list = new List<SortDescriptor>();
    char[] chArray = new char[] { ',' };
    string[] textArray = sortString.Split(chArray);
    for (int i = 0; i < textArray.Length; i++)
    {
        string sortText = textArray[i].Trim();
        int sortLength = sortText.Length;
        bool ascending = true;
 
        if ((sortLength >= 5) && (string.Compare(sortText, sortLength - 4, " ASC", 0, 4, true, System.Globalization.CultureInfo.InvariantCulture) == 0))
        {
            sortText = sortText.Substring(0, sortLength - 4).Trim();
        }
        else if ((sortLength >= 6) && (string.Compare(sortText, sortLength - 5, " DESC", 0, 5, true, System.Globalization.CultureInfo.InvariantCulture) == 0))
        {
            ascending = false;
            sortText = sortText.Substring(0, sortLength - 5).Trim();
        }
 
        if (sortText.StartsWith("["))
        {
            if (!sortText.EndsWith("]"))
            {
                throw new ArgumentException("Invalid sort expression");
            }
 
            sortText = sortText.Substring(1, sortText.Length - 2);
        }
 
        list.Add(new SortDescriptor(sortText, ascending ? ListSortDirection.Ascending : ListSortDirection.Descending));
    }
 
    return list;
}
 
private string GetExpression()
{
    StringBuilder stringBuilder = new StringBuilder();
    for (int i = 0; i < this.Count; i++)
    {
        string direction = "ASC";
        if (this[i].Direction == ListSortDirection.Descending)
        {
            direction = "DESC";
        }
 
        string delimiter = "";
        if (this.Count > 1 && i < this.Count - 1)
        {
            delimiter = ",";
        }
        stringBuilder.Append(string.Format("{0} {1}{2}", this[i].PropertyName, direction, delimiter));
    }
 
    return stringBuilder.ToString();
}


/// <summary>
/// Gets or sets the expression.
/// </summary>
/// <value>The expression.</value>
public virtual string Expression
{
    get
    {
        return this.GetExpression();
    }
    set
    {
        if (string.IsNullOrEmpty(value))
        {
            this.Clear();
            return;
        }
 
        this.ParseSortString(value);
        OnPropertyChanged(new PropertyChangedEventArgs("Expression"));
    }
}
 
private void ParseSortString(string sortString)
{
    this.BeginUpdate();
    this.Clear();
 
    this.AddRange(DataStorageHelper.ParseSortString(sortString).ToArray());
 
    this.EndUpdate();
}

I hope this helps.

Kind regards,
Julian Benkov
the Telerik team
Q3’12 of RadControls for WinForms is available for download (see what's new). Get it today.
Tags
GridView
Asked by
Micah
Top achievements
Rank 1
Answers by
Emanuel Varga
Top achievements
Rank 1
Micah
Top achievements
Rank 1
Julian Benkov
Telerik team
Share this question
or