Grouping on DataGridComboBoxColumn

Sep 29, 2013 at 5:51 PM
Edited Sep 29, 2013 at 6:09 PM
Hi,

One of my columns is of type "Controls:DataGridComboBoxColumn" that shows Student Name and the value behind is Student ID. The code is:
<Controls:DataGridComboBoxColumn Header="Student Name" SelectedValueBinding="{Binding StudentID}" ItemsSource="{Binding Students, Source={StaticResource DatabaseDataSet}}"  DisplayMemberPath="StudentName" SelectedValuePath="StudentID"/>
When I group the rows by that column, the grouping worked fine. The only issue is the group headers are showing the Student ID's. Is there anyway to show Student Names instead of ID's in the group headers?

Thanks in advance,
Topvis
Coordinator
Sep 29, 2013 at 6:19 PM
Hi,

Yes it is possible.

Try to set Style for
<Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}">

http://stackoverflow.com/questions/2147702/wpf-binding-to-current-item-from-within-group-header-style
http://stackoverflow.com/questions/5675132/how-to-customize-group-header-in-datagrid-grouping

Let me know if this dosent help you

Regards,
bpoojary
Sep 30, 2013 at 1:18 AM
Hi bpoojary, thanks for your quick response. I checked the 2 links you recommended but I didn't work it out. Could you help with a little more details?
The datagrid I'm using is the WPFExtendedDataGrid. Where should I put <Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}"> ?
Coordinator
Sep 30, 2013 at 8:00 PM
Hi,

I tried too , still no luck.
Can you share with me one demo application?
Are you fine with any work around?

Regards,
bpoojary
Coordinator
Sep 30, 2013 at 8:36 PM
Hi,

I guess I got the solution, will post in few Hrs.

Regards,
bpoojary
Coordinator
Sep 30, 2013 at 8:59 PM
Here is the solution!!!

In code behind after InitializeComponent method put this lines of codes
grid.GroupStyle.Clear();
var groupStyle = FindResource("CustomGroupStyle");
grid.GroupStyle.Add((GroupStyle)groupStyle);
Add this Converter class anywhere
public class GroupByConverter:IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            string name = System.Convert.ToString(values[0]);
            var cvg = values[1] as System.Windows.Data.CollectionViewGroup;
            var grid = (ExtendedDataGrid) values[2];
            if (cvg!=null)
            {
                var cvs = CollectionViewSource.GetDefaultView(grid.ItemsSource);
                int index = cvs.GroupDescriptions.Count-1;
                while (cvg != null && !cvg.IsBottomLevel)
                {
                    cvg = cvg.Items[0] as CollectionViewGroup;
                    index--;
                }
                var propertyGroupDescription = cvs.GroupDescriptions[index] as PropertyGroupDescription;
                if (propertyGroupDescription != null)
                {
                    string columnName = propertyGroupDescription.PropertyName;

                    var isEnumType = false;
                    string enumValue = string.Empty;
                    if (grid.ItemsSource is DataView)
                    {
                        var dv = grid.ItemsSource as DataView;
                        var baseType = dv.Table.Columns[columnName].DataType.BaseType;
                        if (baseType != null)
                        {
                            isEnumType = baseType.ToString().Equals("System.Enum");
                            if (isEnumType)
                                enumValue = Enum.Parse(dv.Table.Columns[columnName].DataType, name).ToString();
                        }
                    }
                    else if (CollectionViewSource.GetDefaultView(grid.ItemsSource) != null)
                    {
                        var readOnlyCollection = (((ListCollectionView)(CollectionViewSource.GetDefaultView(grid.ItemsSource)))).ItemProperties;
                        if (readOnlyCollection != null)
                        {
                            var item =
                                readOnlyCollection.First(
                                    c => c.Name == columnName);
                            if (item.PropertyType.BaseType != null && item.PropertyType.BaseType.ToString() == "System.Enum")
                            {
                                isEnumType = true;
                                enumValue = Enum.Parse(item.PropertyType, name).ToString();
                            }
                        }
                    }
                    if (isEnumType)
                        return enumValue;
                }
            }
            return name;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
In your Windows Resources add this

As the space is restricted Check my post for xaml changes

Regards,
bpoojary
Coordinator
Sep 30, 2013 at 9:00 PM
Part 2 : Add this in xaml

Add this in your Window Resources
<Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type GroupItem}" >
                        <ControlTemplate.Resources>
                            <Style x:Key="ToggleButtonStyle"  TargetType="ToggleButton">
                                <Setter Property="Background" Value="Transparent"/>
                                <Setter Property="IsEnabled" Value="True" />
                                <Setter Property="IsTabStop" Value="False" />
                                <Setter Property="Cursor" Value="Hand"/>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="ToggleButton">
                                            <Grid x:Name="Button" Margin="0,4,0,0" HorizontalAlignment="Right"
                               VerticalAlignment="Top" Width="16" Height="16">
                                                <Rectangle Stroke="{DynamicResource DynamicDefaultControlForegroundBrush}" HorizontalAlignment="Stretch"
                                   VerticalAlignment="Stretch" Width="Auto" Height="Auto"
                                   RadiusX="3" RadiusY="3" Fill="Transparent">
                                                </Rectangle>
                                                <Rectangle x:Name="CollapsedVisual" HorizontalAlignment="Left"
                                   VerticalAlignment="Top" Width="2" Height="8" RadiusX="0" Visibility="Collapsed"
                                   RadiusY="0" Fill="{DynamicResource DynamicDefaultControlForegroundBrush}" Margin="7,4,0,0" />
                                                <Rectangle RadiusX="0" RadiusY="0" Fill="{DynamicResource DynamicDefaultControlForegroundBrush}"
                                   HorizontalAlignment="Left" Margin="4,7,0,0"
                                   VerticalAlignment="Top" Width="8" Height="2" />
                                            </Grid>
                                            <ControlTemplate.Triggers>
                                                <Trigger Property="IsChecked" Value="False">
                                                    <Setter TargetName="CollapsedVisual" Property="Visibility" Value="Visible"/>
                                                </Trigger>
                                            </ControlTemplate.Triggers>
                                        </ControlTemplate>

                                    </Setter.Value>
                                </Setter>
                            </Style>
                            <Style x:Key="{x:Type Expander}"  TargetType="{x:Type Expander}">
                                <Setter Property="Foreground" Value="{DynamicResource DynamicDefaultControlForegroundBrush}"/>
                                <Setter Property="Background" Value="Transparent"/>
                                <Setter Property="Padding" Value="1"/>
                                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                                <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                                <Setter Property="BorderBrush" Value="{DynamicResource DynamicSeperatorBrush}"/>
                                <Setter Property="BorderThickness" Value="1"/>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type Expander}">
                                            <Border BorderBrush="{DynamicResource DynamicSeperatorBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="3" SnapsToDevicePixels="true">
                                                <DockPanel>

                                                    <Border DockPanel.Dock="Top" BorderBrush="{DynamicResource DynamicSeperatorBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                                                        <StackPanel Orientation="Horizontal">
                                                            <ToggleButton Style="{StaticResource ToggleButtonStyle}" x:Name="HeaderSite" ContentTemplate="{TemplateBinding HeaderTemplate}" ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" Content="{TemplateBinding Header}"  Foreground="{TemplateBinding Foreground}" FontWeight="{TemplateBinding FontWeight}" FocusVisualStyle="{DynamicResource ExpanderHeaderFocusVisual}" FontStyle="{TemplateBinding FontStyle}" FontStretch="{TemplateBinding FontStretch}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalAlignment="Left" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" MinWidth="0" MinHeight="0" Padding="{TemplateBinding Padding}"  VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                                            <TextBlock FontWeight="Bold" VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource AncestorType=Expander}, Path=Header}"></TextBlock>
                                                        </StackPanel>

                                                    </Border>

                                                    <ContentPresenter x:Name="ExpandSite" DockPanel.Dock="Bottom" Focusable="false" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                                </DockPanel>
                                            </Border>
                                            <ControlTemplate.Triggers>
                                                <Trigger Property="IsExpanded" Value="true">
                                                    <Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/>
                                                </Trigger>
                                                <Trigger Property="IsEnabled" Value="false">
                                                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                                                </Trigger>
                                            </ControlTemplate.Triggers>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </ControlTemplate.Resources>
                        <Expander IsExpanded="True"   BorderBrush="{DynamicResource DynamicHeaderPressedBackgroundBrush}" BorderThickness="1,0.5,1,0.5" Margin="4,0,0,3" Expanded="ExpanderExpanded" Collapsed="ExpanderExpanded"
                          Background="{DynamicResource DynamicHeaderBackgroundBrush}" >
                            <Expander.Resources>
                                <UserControls:GroupByConverter x:Key="GroupByConverter"></UserControls:GroupByConverter>
                            </Expander.Resources>
                            <Expander.Header>
                                <MultiBinding Converter="{StaticResource GroupByConverter}">
                                    <Binding Path="Name"/>
                                    <Binding Path="."/>
                                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ExtendedGridControl:ExtendedDataGrid}"/>
                                </MultiBinding>
                            </Expander.Header>
                                <ItemsPresenter />
                        </Expander>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <GroupStyle x:Key="CustomGroupStyle" ContainerStyle="{StaticResource GroupHeaderStyle}">
            <GroupStyle.Panel>
                <ItemsPanelTemplate>
                    <!--<Primitives:DataGridRowsPresenter Margin="4,0,0,0" />-->
                    <Classes:CustomDataGridRowsPresenter />
                </ItemsPanelTemplate>
            </GroupStyle.Panel>
        </GroupStyle>
Regards,
bpoojary
Coordinator
Sep 30, 2013 at 9:00 PM
Above solution worked for me , you let me know if you still face any issue.
Will try to fix it.

Regards,
bpoojary
Coordinator
Oct 1, 2013 at 5:06 AM
Hi,

One more thing you will have to copy event ExpanderExpanded event ,FindParent and FindChild from ExtendedDataGrid project to your window as of now.
Once this piece of code is running will realease new version which woulf work directly for you.


Regards,
bpoojary
Coordinator
Oct 1, 2013 at 6:40 PM
Hi,

Did you try my suggestion?

Regards,
bpoojary
Oct 3, 2013 at 2:59 AM
hi bpoojary,

I haven't got chance to try yet. I'll try it later this week and let you know if it works.

Thanks so much for your help!

topvis
Oct 3, 2013 at 5:04 PM
I tried your solution. Because I'm using VB.net so I had to convert the C# codes to VB. I got 2 problems:

(1) In Style definition, the 2 DynamicResources DynamicHeaderPressedBackgroundBrush and DynamicHeaderBackgroundBrush cannot be resolved. But it didn't affect building the project.
                        <Expander IsExpanded="True"
                              BorderBrush="{DynamicResource DynamicHeaderPressedBackgroundBrush}"
                              BorderThickness="1,0.5,1,0.5"
                              Margin="4,0,0,3" 
                              Expanded="ExpanderExpanded" 
                              Collapsed="ExpanderExpanded"
                              Background="{DynamicResource DynamicHeaderBackgroundBrush}" >
(2) When the program is running and I dragged a column to the group header, an exception "Unable to cast object of type 'System.Windows.Data.BindingListCollectionView' to type 'System.Windows.Data.ListCollectionView'" occurred on the code below:
C# code in GroupByConverter:

    var readOnlyCollection = (((ListCollectionView)(CollectionViewSource.GetDefaultView(grid.ItemsSource)))).ItemProperties;

I Converted it to VB for my VB project:

    Dim readOnlyCollection As Object = CType(CollectionViewSource.GetDefaultView(grid.ItemsSource), ListCollectionView).ItemProperties
Again, I'm really a newbie so I might have missed some simple things there. Your help is really appreciated.
Coordinator
Oct 3, 2013 at 8:00 PM
Hi,

Let me know what you are Binding,if possible send me dummy project.

Regards,
bpoojary


Oct 4, 2013 at 4:03 PM
I have uploaded my dummy project here

The ExtendedDataGrid part in my MainWindow.xaml is:
    <Grid DataContext="{StaticResource StudentsViewSource}">
        <TextBlock Foreground="Red" Text="Drag column Name to group, the exception will occur" />
        <ExtendedGridControl:ExtendedDataGrid x:Name="grid"
                                              Margin="0,27,0,0"
                                              AutoGenerateColumns="False"
                                              ClipboardCopyMode="IncludeHeader"
                                              EnableRowVirtualization="True"
                                              FrozenColumnCount="2"
                                              GridLinesVisibility="Horizontal"
                                              IsSynchronizedWithCurrentItem="True"
                                              ItemsSource="{Binding Source={StaticResource StudentsViewSource}}"
                                              RowDetailsVisibilityMode="VisibleWhenSelected"
                                              RowHeaderWidth="20"
                                              RowHeight="26">
            <Controls:DataGrid.Columns>
            <Controls:DataGridComboBoxColumn Width="150"
                                               DisplayMemberPath="Name"
                                               Header="Name"
                                               ItemsSource="{Binding Students, Source={StaticResource DB_ADataSet}}"
                                               SelectedValueBinding="{Binding ID}"
                                               SelectedValuePath="ID" />
            </Controls:DataGrid.Columns>
        </ExtendedGridControl:ExtendedDataGrid>
    </Grid>
Coordinator
Oct 4, 2013 at 8:03 PM
Hi,

I am getting compilation error.

Error 24 file 'My Project\AssemblyInfo.vb' could not be found C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\vbc DGDragDrop
Error 25 file 'My Project\MyExtensions\MyWpfExtension.vb' could not be found C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\vbc DGDragDrop
Error 26 file 'My Project\Resources.Designer.vb' could not be found C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\vbc DGDragDrop
Error 27 file 'My Project\Settings.Designer.vb' could not be found C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\vbc DGDragDrop
Error 28 'MySettings' is not a member of 'DGDragDrop'. C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\DB_ADataSet.Designer.vb 795 47 DGDragDrop
Error 29 Unable to open module file 'C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\My Project\AssemblyInfo.vb': The system cannot find the file specified. C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\My Project\AssemblyInfo.vb 1 1 DGDragDrop
Error 30 Unable to open module file 'C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\My Project\MyExtensions\MyWpfExtension.vb': The system cannot find the file specified. C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\My Project\MyExtensions\MyWpfExtension.vb 1 1 DGDragDrop
Error 31 Unable to open module file 'C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\My Project\Resources.Designer.vb': The system cannot find the file specified. C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\My Project\Resources.Designer.vb 1 1 DGDragDrop
Error 32 Unable to open module file 'C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\My Project\Settings.Designer.vb': The system cannot find the file specified. C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\My Project\Settings.Designer.vb 1 1 DGDragDrop
Error 33 The name "DB_ADataSet" does not exist in the namespace "clr-namespace:DGDragDrop". C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\MainWindow.xaml 18 9 DGDragDrop
Error 34 The name "GroupByConverter" does not exist in the namespace "clr-namespace:DGDragDrop". C:\Users\admin\Downloads\DGDragDrop\DGDragDrop\DGDragDrop\MainWindow.xaml 169 33 DGDragDrop
Oct 4, 2013 at 8:45 PM
Oh, I missed something. I've uploaded a new one. Can you download it again?

I can't attach the database so when you run it no records will be loaded.