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

Group by first letter

3 Answers 80 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Inger Marie
Top achievements
Rank 1
Inger Marie asked on 19 Mar 2015, 08:23 AM
Hi,
I have a bunch of different RadGridViews, and in each RadGridView there are columns containing names. I want these columns to be grouped by first letter - however I want this:

* '\0' and String.Empty and null must be grouped together and showed as String.Empty (or null, the user cannot see the difference).
* Upper case and lower case (such as 'g' and 'G') must be grouped together and showed by the upper case variant.
* Leading spaces, such as in "     Telerik" should be ignored (so "       Telerik" and "Tony" should both be grouped under "T").

Is there any way to do this, without creating a separate FirstLetterInName-property on all my ViewModels that has the Name-property (which is a lot)?

I tried using the GroupHeaderTemplate, but that gets applied after the grouping and only affects the name of the group, not how the grouping is calculated:

 <telerik:GridViewDataColumn x:Name="_contactNameColumn" Width="SizeToHeader"
                                Header="Name"
                                DataMemberBinding="{Binding ContactName}"
                                GroupMemberPath="ContactName[0]"
                                GroupHeaderTemplate="{StaticResource NameGroupTemplate}"/>

3 Answers, 1 is accepted

Sort by
0
Dimitrina
Telerik team
answered on 21 Mar 2015, 03:21 PM
Hello Inger,

In order to define your own way of grouping, you can apply a generic GroupDescriptor. Please refer to our online documentation on Using generic GroupDescriptor for more details.

Regards,
Dimitrina
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Inger Marie
Top achievements
Rank 1
answered on 27 Mar 2015, 08:45 AM
I am sorry, but I cant find a way to do this. I wanted to attach a sample project, but that is not allowed. So I paste in the code instead.

In this project, I want to group Name and Industry Name on the trimmed values first letter. I want to have " " and String.Empty and null to end up in the same group.

I want Selected, Industry Code, Country and Description to be grouped traditionally.

I do not understand how I can do this by using a generic GroupDescriptor because I do not know how I can make the RadGridView use this group selector on some columns but not others.

Can you help me please?


public partial class MainWindow : Window, INotifyPropertyChanged
 {
     public MainWindow()
     {
         InitializeComponent();
         DataContext = this;
 
 
         Companies.Add(new Company(" ", "2345", "Beverages", "PL", GetDescription()));
         Companies.Add(new Company(String.Empty, null, null, "DE", GetDescription()));
         Companies.Add(new Company("Absolute", null, null, "DE", GetDescription()));
         Companies.Add(new Company(" Alcohol", "2345", "Beverages", "DK", GetDescription()));
         Companies.Add(new Company("Bikes", "4354", "Transportation", "DE", GetDescription()));
         Companies.Add(new Company(null, "4354", "Transportation", "PL", GetDescription()));
         Companies.Add(new Company("Whiskey", "2345", "Beverages", "UK", GetDescription()));
     }
 
     private string GetDescription()
     {
         List<string> words = new List<string>();
         for (int i = 0; i < RandomSampleData.GetInt(new RandomBoundary(2, 6)); i++)
         {
             words.Add(RandomSampleData.GetString());
         }
         return String.Join(" ", words);
     }
 
 
     #region INotifyPropertyChanged Members
 
     /// <summary>
     /// Raises this object's PropertyChanged event.
     /// </summary>
     /// <param name="propertyName">The property that has a new value.</param>
     protected void RaisePropertyChanged(string propertyName)
     {
         if (PropertyChanged != null)
         {
             PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
         }
     }
 
     public event PropertyChangedEventHandler PropertyChanged;
 
     private void CurrentProjectSuppliers_OnFilterOperatorsLoading(object sender, FilterOperatorsLoadingEventArgs e)
     {
         e.AvailableOperators.Remove(FilterOperator.IsContainedIn);
         e.AvailableOperators.Remove(FilterOperator.IsNotContainedIn);
 
         if (e.Column.Equals(_nameColumn)
             || e.Column.Equals(_iNameColumn)
             || e.Column.Equals(_descriptionColumn))
         {
             e.AvailableOperators.Remove(FilterOperator.IsEmpty);
             e.AvailableOperators.Remove(FilterOperator.IsGreaterThan);
             e.AvailableOperators.Remove(FilterOperator.IsGreaterThanOrEqualTo);
             e.AvailableOperators.Remove(FilterOperator.IsLessThan);
             e.AvailableOperators.Remove(FilterOperator.IsLessThanOrEqualTo);
             e.AvailableOperators.Remove(FilterOperator.IsNotEmpty);
             return;
         }
         if (e.Column.Equals(_iCodeColumn))
         {
             e.AvailableOperators.Remove(FilterOperator.DoesNotContain);
             e.AvailableOperators.Remove(FilterOperator.Contains);
             e.AvailableOperators.Remove(FilterOperator.EndsWith);
             e.AvailableOperators.Remove(FilterOperator.IsEmpty);
             e.AvailableOperators.Remove(FilterOperator.IsGreaterThanOrEqualTo);
             e.AvailableOperators.Remove(FilterOperator.IsLessThanOrEqualTo);
             e.AvailableOperators.Remove(FilterOperator.IsNotEmpty);
             e.AvailableOperators.Remove(FilterOperator.IsNotNull);
             e.AvailableOperators.Remove(FilterOperator.IsNull);
             return;
         }
 
     }
 
     private void CurrentProjectSuppliers_OnFieldFilterEditorCreated(object sender, EditorCreatedEventArgs e)
     {
 
         StringFilterEditor stringFilterEditor = e.Editor as StringFilterEditor;
         if (stringFilterEditor != null)
         {
             stringFilterEditor.MatchCaseVisibility = Visibility.Hidden;
             stringFilterEditor.IsCaseSensitive = false;
         }
 
     }
 
     #endregion
 
     private readonly ObservableCollection<Company> _companies = new ObservableCollection<Company>();
 
     public ObservableCollection<Company> Companies
     {
         get { return _companies; }
     }
 }

<Window x:Class="Sandbox.MainWindow"
        xmlns:Sandbox="clr-namespace:Sandbox"
        Title="MainWindow">
    
<Window.Resources>
        <SolidColorBrush x:Key="RowBrush" Color="White" />
        <SolidColorBrush x:Key="SelectedRowColor" Color="#FF3399FF" />
        <SolidColorBrush x:Key="MouseOverRowColor" Color="#FFA5A5A5" />
        <SolidColorBrush x:Key="AlternateRowBrush" Color="#E9F0FF" />
         
    <Style TargetType="{x:Type telerik:GridViewRow}" x:Key="RadGridViewRowStyle">
            <Setter Property="Background" Value="{StaticResource RowBrush}" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{StaticResource SelectedRowColor}" />
                </Trigger>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="{StaticResource MouseOverRowColor}" />
                </Trigger>
            </Style.Triggers>
        </Style>
 
        <Style TargetType="{x:Type telerik:GridViewRow}" x:Key="RadGridViewAlternateRowStyle">
            <Setter Property="Background" Value="{StaticResource AlternateRowBrush}" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{StaticResource SelectedRowColor}" />
                </Trigger>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="{StaticResource MouseOverRowColor}" />
                </Trigger>
            </Style.Triggers>
        </Style>
     
     
        <Style TargetType="{x:Type telerik:RadGridView}" x:Key="RadGridViewStyle" >
            <Setter Property="RowIndicatorVisibility" Value="Collapsed" />
            <Setter Property="AlternationCount"
                Value="2" />
 
            <Setter Property="AutoGenerateColumns"
                Value="False" />
            <Setter Property="IsFilteringAllowed"               
                Value="False" />
            <Setter Property="CanUserInsertRows"
                Value="False" />
            <Setter Property="CanUserDeleteRows"
                Value="False" />
            <Setter Property="RowStyle" Value="{StaticResource RadGridViewRowStyle}" />
            <Setter Property="AlternateRowStyle" Value="{StaticResource RadGridViewAlternateRowStyle}" />
        </Style>
 
        <Sandbox:Bool2Visibility TrueResult="Visible" FalseResult="Collapsed" x:Key="False2Collapsed"/>
        <Sandbox:Bool2Visibility TrueResult="Collapsed" FalseResult="Visible" x:Key="True2Collapsed"/>
 
    </Window.Resources>
     
    <telerik:RadGridView x:Name="_currentProjectSuppliers"
        FrozenColumnsSplitterVisibility="Collapsed"
                         FilteringMode="Popup"
                         IsFilteringAllowed="True"
                        Style="{StaticResource RadGridViewStyle}"
                        ItemsSource="{Binding Companies}"
                        IsSynchronizedWithCurrentItem="False"
                         HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
                         VerticalAlignment="Stretch" VerticalContentAlignment="Stretch"
                            VisibleRowsHeight="25"
                            CanUserSortColumns="True"
                         CanUserSortGroups="True"
                         FieldFilterEditorCreated ="CurrentProjectSuppliers_OnFieldFilterEditorCreated"
                         FilterOperatorsLoading="CurrentProjectSuppliers_OnFilterOperatorsLoading">
        <telerik:RadGridView.Resources>
            <ResourceDictionary>
                <!--<LinearGradientBrush x:Key="GridView_FilterIconBackground_Filtered" EndPoint="0,0.5" StartPoint="1,0.5">
                    <GradientStop Color="#FFFF7300" Offset="0"/>
                    <GradientStop Color="#FFFFF400" Offset="0.8"/>
                </LinearGradientBrush>-->
 
                <Style TargetType="telerik:GridViewCell">
                    <Setter Property="Padding" Value="2"/>
                    <Setter Property="VerticalContentAlignment" Value="Center"/>
                    <Setter Property="HorizontalContentAlignment" Value="Right" />
                </Style>
 
                <Style TargetType="telerik:GridViewCell" x:Key="CenteredCell">
                    <Setter Property="HorizontalContentAlignment" Value="Center" />
                </Style>
 
                <Style TargetType="telerik:GridViewCell" x:Key="LefteredCell">
                    <Setter Property="HorizontalContentAlignment" Value="Left" />
                </Style>
            </ResourceDictionary>
        </telerik:RadGridView.Resources>
        <telerik:RadGridView.SortDescriptors>
            <telerik:SortDescriptor Member="NaceCode.NaceCode" SortDirection="Ascending" />
        </telerik:RadGridView.SortDescriptors>
        <telerik:RadGridView.Columns>
 
 
            <telerik:GridViewDataColumn x:Name="_isSelectedColumn"
                                      IsSortable="True"
                                    IsFilterable="True"
                                    ShowFieldFilters="False"
                                    FilterMemberPath="IsSelected"
                                    SortMemberPath="IsSelected"
                                    Width="SizeToHeader"
                                    CellStyle="{StaticResource CenteredCell}"
                                    DataMemberBinding="{Binding Path=(Sandbox:Company.IsSelected)}" IsReadOnly="True"
                                    GroupMemberPath="IsSelected">
                <telerik:GridViewDataColumn.Header>
                    <TextBlock Text="Selected"  />
                </telerik:GridViewDataColumn.Header>
                <telerik:GridViewDataColumn.CellTemplate>
                    <DataTemplate DataType="{x:Type Sandbox:Company}">
                        <!--<Image Height="16" Width="16"
                            VerticalAlignment="Center" HorizontalAlignment="Center"
                           Source="{StaticResource SingleCheckImageSmall}"
                           Visibility="{Binding IsSelected, Converter={StaticResource False2Collapsed}}" />-->
                        <TextBlock Height="16" Width="16"
                            VerticalAlignment="Center" HorizontalAlignment="Center"
                          Text="Selected"
                           Visibility="{Binding IsSelected, Converter={StaticResource False2Collapsed}}" />
                    </DataTemplate>
                </telerik:GridViewDataColumn.CellTemplate>
            </telerik:GridViewDataColumn>
 
             
 
            <telerik:GridViewDataColumn x:Name="_nameColumn"
                                    Width="260"
                                    IsFilterable="True"
                                    IsSortable="True"
                                    ShowDistinctFilters="False"
                                    FilterMemberPath="Name"
                                    CellStyle="{StaticResource LefteredCell}"
                                    DataMemberBinding="{Binding Path=(Sandbox:Company.Name)}" IsReadOnly="True"
                                         SortMemberPath="Name"
                                        GroupMemberPath="Name"
                                    IsGroupable="True">
                <!--GroupMemberPath="Name[0]"-->
                <telerik:GridViewDataColumn.Header>
                    <TextBlock Text="Name"
                                           ToolTip="Name" />
                </telerik:GridViewDataColumn.Header>
            </telerik:GridViewDataColumn>
 
            <!--SortMemberPath="NaceCode.NaceCode"-->
            <telerik:GridViewDataColumn x:Name="_iCodeColumn"
                                   IsSortable="True"
                                    IsFilterable="True"
                                    ShowDistinctFilters="False"
                                    ShowFieldFilters="True"
                                    FilterMemberPath="IndustryCode"
                                    GroupMemberPath="IndustryCode"
                                        SortMemberPath="IndustryCode"
                                    Width="SizeToHeader"
                                    CellStyle="{StaticResource LefteredCell}"
                                    DataMemberBinding="{Binding Path=(Sandbox:Company.IndustryCode)}" IsReadOnly="True"
                                    IsGroupable="True">
                <telerik:GridViewDataColumn.Header>
                    <TextBlock Text="Industry Code"
                                           ToolTip="Industry Code" />
                </telerik:GridViewDataColumn.Header>
            </telerik:GridViewDataColumn>
 
 
            <!--GroupMemberPath="NaceCode.IndustryName[0]"-->
            <telerik:GridViewDataColumn x:Name="_iNameColumn"
                                   IsSortable="True"
                                    IsFilterable="True"
                                   ShowDistinctFilters="False"
                                     FilterMemberPath="IndustryName"
                                         SortMemberPath="IndustryName"
                                        GroupMemberPath="IndustryName"
                                    Width="220"
                                    CellStyle="{StaticResource LefteredCell}"
                                    MaxWidth="320"
                                    DataMemberBinding="{Binding Path=(Sandbox:Company.IndustryName)}" IsReadOnly="True">
                <telerik:GridViewDataColumn.Header>
                    <TextBlock Text="Industry Name"
                                           ToolTip="Industry Name" />
                </telerik:GridViewDataColumn.Header>
            </telerik:GridViewDataColumn>
 
 
            <telerik:GridViewDataColumn x:Name="_countryColumn"
                                   IsSortable="True"
                                    IsFilterable="True"
                                    ShowFieldFilters="False"
                                    FilterMemberPath="CountryISOName"
                                         SortMemberPath="CountryISOName"
                                    Width="SizeToHeader"
                                    CellStyle="{StaticResource LefteredCell}"
                                    DataMemberBinding="{Binding Path=(Sandbox:Company.CountryISOName)}" IsReadOnly="True"
                                    GroupMemberPath="Country.ShortNameISO">
                <telerik:GridViewDataColumn.Header>
                    <TextBlock Text="Country"
                                           ToolTip="Country" />
                </telerik:GridViewDataColumn.Header>
            </telerik:GridViewDataColumn>
 
 
            <!--GroupMemberPath="Master.Name[0]"-->
            <telerik:GridViewDataColumn x:Name="_descriptionColumn"
                                   IsSortable="True"
                                    ShowDistinctFilters="False"
                                    IsFilterable="True"
                                    FilterMemberPath="Description"
                                         SortMemberPath="Description"
                                    Width="SizeToHeader"
                                    CellStyle="{StaticResource LefteredCell}"
                                    DataMemberBinding="{Binding Path=(Sandbox:Company.Description)}" IsReadOnly="True">
                <telerik:GridViewDataColumn.Header>
                    <TextBlock Text="Description"
                                           ToolTip="Description" />
                </telerik:GridViewDataColumn.Header>
            </telerik:GridViewDataColumn>
 
        </telerik:RadGridView.Columns>
    </telerik:RadGridView>
</Window>

public class Bool2Visibility : IValueConverter
   {
       public Visibility TrueResult { get; set; }
       public Visibility FalseResult { get; set; }
 
       public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
       {
           if (value == null) return FalseResult;
           return ((value is bool?) ? (bool?)value == true : (bool)value) ? TrueResult : FalseResult;
       }
 
       public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
       {
           throw new NotImplementedException();
       }
 
 
       Visibility Method(object value, Type targetType, object parameter, CultureInfo culture)
       {
           return ((value is bool?) ? (bool?)value == true : (bool)value) ? TrueResult : FalseResult;
       }
   }

public class Company : ViewModelBase
  {
 
      public Company(string name, string iCode, string iName, string country, string description)
      {
          Name = name;
          IndustryCode = iCode;
          IndustryName = iName;
          CountryISOName = country;
          Description = description;
      }
      private bool _isSelected;
      private string _name;
      private string _industryCode;
      private string _industryName;
      private string _countryISOName;
      private string _description;
 
      public bool IsSelected
      {
          get { return _isSelected; }
          set { _isSelected = value; RaisePropertyChanged(() => IsSelected);}
      }
 
      public string Name
      {
          get { return _name; }
          set { _name = value; RaisePropertyChanged(() => Name); }
      }
 
      public string IndustryCode
      {
          get { return _industryCode; }
          set { _industryCode = value; RaisePropertyChanged(() => IndustryCode); }
      }
 
      public string IndustryName
      {
          get { return _industryName; }
          set { _industryName = value; RaisePropertyChanged(() => IndustryName); }
      }
 
      public string CountryISOName
      {
          get { return _countryISOName; }
          set { _countryISOName = value; RaisePropertyChanged(() => CountryISOName); }
      }
 
      public string Description
      {
          get { return _description; }
          set { _description = value; RaisePropertyChanged(() => Description); }
      }
  }

public class RandomBoundary
  {
      public RandomBoundary(int? minValue, int? maxValue)
      {
          MinValue = minValue;
          MaxValue = maxValue;
      }
      public int? MinValue { get; private set; }
      public int? MaxValue { get; private set; }
  }
 
  public static class RandomSampleData
  {
      private static readonly Random Random = new Random();
 
      public static int GetInt(RandomBoundary boundary = null)
      {
          if (boundary == null || (boundary.MinValue == null && boundary.MaxValue == null))
          {
              return Random.Next();
          }
          if (boundary.MinValue == null)
          {
              Debug.Assert(boundary.MaxValue != null);
              return Random.Next(boundary.MaxValue.Value);
          }
          return Random.Next(boundary.MinValue.Value, boundary.MinValue.Value);
      }
 
      public static bool GetBool()
      {
 
          return Random.Next() % 2 == 0;
      }
 
      public static bool? GetNullableBool()
      {
 
          int x = Random.Next() % 3;
          switch (x)
          {
              case 2:
                  return true;
              case 1:
                  return false;
              default:
                  return new bool?();
          }
      }
 
 
      public static string GetString(string prefix = null, string postfix = null)
      {
          return String.Format("{0}{1}{2}", prefix ?? String.Empty, Random.Next(), postfix ?? String.Empty);
      }
 
 
      public static decimal GetDecimal(RandomBoundary boundary)
      {
          decimal part = (decimal)Random.NextDouble();
          return GetInt(boundary) + part;
      }
 
 
 
      public static decimal? GetNullableDecimal(RandomBoundary boundary)
      {
 
          if (GetBool())
              return GetDecimal(boundary);
          return new decimal?();
      }
 
      public static T GetEnum<T>(T sample)
      {
 
          Array array = Enum.GetValues(typeof(T));
          int index = Random.Next() % array.Length;
          return (T)((IList)array)[index];
      }
 
      public static T GetEnum<T>(T[] allowableValues)
      {
 
          int index = Random.Next() % allowableValues.Length;
          return allowableValues[index];
      }
 
      public static DateTime GetDate(bool inPast = true, int maxDays = 30)
      {
 
          int days = Random.Next(maxDays);
          return inPast ? DateTime.Now.AddDays(-days) : DateTime.Now.AddDays(days);
      }
 
      public static DateTime? GetNullableDate(bool inPast = true, int maxDays = 30)
      {
 
          if (GetBool())
          {
              return GetDate(inPast, maxDays);
          }
          return new DateTime?();
      }
 
  }

Thanks,
Best regards
Inger Marie
0
Dimitrina
Telerik team
answered on 30 Mar 2015, 12:40 PM
Hi Inger,

You can subscribe for the Grouping event of RadGridView and replace the added ColumnGroupDescriptor with a new generic one where you have specified a proper GroupExpression and GroupSortingExpresstion.

Such an example is available in the following forum thread. Would you please try it? In case it does not help, you can open a new support ticket and attach your sample project there.


Regards,
Dimitrina
Telerik
 

See What's Next in App Development. Register for TelerikNEXT.

 
Tags
GridView
Asked by
Inger Marie
Top achievements
Rank 1
Answers by
Dimitrina
Telerik team
Inger Marie
Top achievements
Rank 1
Share this question
or