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}"/>
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
0
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
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?
Thanks,
Best regards
Inger Marie
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:telerik="http://schemas.telerik.com/2008/xaml/presentation" 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
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
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.