Skip to content

WPF Toolkit DataGrid Part IV: TemplateColumns and Row Grouping

by Samuel Moura on June 15th, 2009

This post is part of the WPF Toolkit DataGrid series. Here is a list with the complete set of blog posts:

Introduction

In Part III we got to know a bit better how stuff gets rendered on the WPF DataGrid. We have gone through several samples on how to configure the way data gets displayed on each column by either creating new column types or by styling existing ones.

In Part IV we will have a look into more advanced concepts. First we will see how we can use the DataGridTemplateColumn to imitate the behavior of a DataGridComboBoxColumn and to show a small chart representing the age deviation from average for each player. We will then have a look on how we can group rows on our DataGrid using two separate methodologies.

Roadmap

  • Creating a ComboBox column from a TemplateColumn
  • Using DataGridTemplateColumns to create a chart column
  • Grouping rows using ItemsControl.GroupStyle
  • Fake grouping with the help of the ViewModel

Download sample source code

Here is a list with the samples presented on this blog post:

Creating a ComboBox column from a TemplateColumn

The ItemsSource property of DataGridComboBox column does not allow for you to directly bind to data on your DataContext, at least for now (WPF Toolkit – March 2009 release). It is likely that in a future release binding support will be added (if you want further information on this checkout this CodePlex workitem).

There are a lot of ways in which you could implement this! For instance, you could extend DataGridComboBoxColumn adding binding support on it, you could add the binding support directly to DataGridComboBoxColumn recompiling WPF Toolkit, etc.

The solution I came up with in my application was a simpler one, IMHO. I restyled a DataGridTemplateColumn to behave like a DataGridComboBox column.

This is very simple to accomplish. The only issue I found was that the effort required to actually finding the property to bind to from within the created template – I had to use a tricky binding expression.

You must start by adding to your view model the data you are going to bind to:

 (…)
public IList<string> Categories { get; set; }
(…)
public TeamModel()
{
    Categories = new List<string>
        { "Mini", "Cadet", "Junior", "Senior", "Veteran" };
}
(…)

In order for you to use a DataGridTemplateColumn you must create two specific templates, one for the cell in its default view and one for when it is in editing mode. In the default view of our cell only text will be displayed. You can just add a new template that uses a label to render the selected text:

<DataTemplate x:Key="ComboBoxCellDataTemplate">
    <Label x:Name="lblCombo" Content="{Binding Category}"
           Style="{StaticResource BaseLabelCellStyle}" />
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.Categories}" Value="Both">
            <Setter TargetName="lblCombo" Property="IsEnabled" Value="False" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

As you may have noticed you had to use RelativeSource to find the properties to bind to. Now you have to create the editing mode template that uses a ComboBox and lets the users select which category he wants to set a player in.

<DataTemplate x:Key="ComboBoxCellEditingTemplate">
    <ComboBox x:Name="comboBox"
              ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.Categories}"
              SelectedItem="{Binding Category}"/>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Enabled}" Value="False">
            <Setter TargetName="comboBox" Property="IsEnabled" Value="False" />
        </DataTrigger>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.Categories}" Value="Both">
            <Setter TargetName="comboBox" Property="IsEnabled" Value="False" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

After adding these two DataTemplates to the resources you can change the definition of the Category column to use the DataGridTemplateColumn with these two specific templates.

<WpfToolkit:DataGridTemplateColumn
    Header="Category" Width="1*"
    CellTemplate="{StaticResource ComboBoxCellDataTemplate}"
    CellEditingTemplate="{StaticResource ComboBoxCellEditingTemplate}"/>

It could not get simpler than this! You have just made a ComboBoxColumn out of a DataGridTemplateColumn.

This is how our sample application is looking after these changes:

WpfToolkitDataGrid-ss015a

You can download a working sample of this code by following this link.

Using DataGridTemplateColumns to create a chart column

Each player shown in the DataGrid has an age associated with him. For each player we will be presenting a chart column picturing the deviation of his age towards the team average.

All calculations regarding the team age average and each players deviation should be done in the backend. Basically you will have to change the code behind file for TeamView since there is where we setup the view model for the view (this is definitely a bad practice – it is being done this way for simplicity). In the DeviationChart column we will expose the DeviationPercentage previously calculated. This value will be used to calculate the width of the bars to draw our chart with.

Essentially this is the code used to calculate these values:

(…)
SetupTeamAgeAverage(playerAges.Where(player => player.Parent == alphaTeam));

(…)

private static void SetupTeamAgeAverage(IEnumerable<IPlayerAge> teamPlayers)
{
    double teamAgeAverage = teamPlayers.Average(x => x.Age);
    foreach (var player in teamPlayers)
    {
        player.Deviation = player.Age - teamAgeAverage;
        player.DeviationPercentage =
            (player.Age - teamAgeAverage) / teamAgeAverage;
    }
}
(…)

Now that the data is processed you need to create a new element style to apply on the DataGridTemplateColumn that picks this value and transforms it to a chart.

Deviation percentage goes from -1 to 1. If it is negative we will create a bar on the left of the chart, otherwise a bar will be added on the right. The length of the bar will be proportional to the amount of deviation. All this will be done using standard grids, background colors and star notation on grid column widths.

Since we do not have a direct way of converting a value into a percentage of width we will be doing so in a hacky way by using an IValueConverter (you can see the actual implementation of the converter by downloading the sample code).

After creating the converter you will have to add this new style to the resources of your view:

<Style x:Key="BarChartCellStyle" TargetType="{x:Type WpfToolkit:DataGridCell}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type WpfToolkit:DataGridCell}">
                <Grid Background="{TemplateBinding Background}">
                    <Grid x:Name="BarChart" Background="LightBlue"
                          Height="14"  Margin="2,0,2,0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition x:Name="lowerToleranceColumn"
                                              Width="*"/>
                            <ColumnDefinition Width="1"/>
                            <ColumnDefinition x:Name="upperToleranceColumn"
                                              Width="*"/>
                        </Grid.ColumnDefinitions>

                        <Grid Margin="2,0,1,0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="{Binding DeviationPercentage,
                                    Converter={StaticResource percentageWidthConverter},
                                    ConverterParameter=1}"/>
                                <ColumnDefinition Width="{Binding DeviationPercentage,
                                    Converter={StaticResource percentageWidthConverter},
                                    ConverterParameter=2}"/>
                            </Grid.ColumnDefinitions>
                            <Border x:Name="LowerBarChart" Grid.Column="1"
                                    Height="10" Background="MediumBlue">
                                <TextBlock x:Name="LowerToleranceLabel"
                                           Text="&lt;" Foreground="White"
                                           HorizontalAlignment="Left" VerticalAlignment="Center"
                                           Margin="2,-2,0,0"/>
                            </Border>
                        </Grid>

                        <Border Grid.Column="1" Width="1" Background="Gray" />

                        <Grid Grid.Column="2" Margin="1,0,2,0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="{Binding DeviationPercentage,
                                    Converter={StaticResource percentageWidthConverter},
                                    ConverterParameter=3}"/>
                                <ColumnDefinition Width="{Binding DeviationPercentage,
                                    Converter={StaticResource percentageWidthConverter},
                                    ConverterParameter=4}"/>
                            </Grid.ColumnDefinitions>
                            <Border x:Name="UpperBarChart" Height="10" Background="DarkOrange">
                                <TextBlock x:Name="UpperToleranceLabel"
                                           Text="&gt;" Foreground="White"
                                           HorizontalAlignment="Right" VerticalAlignment="Center"
                                           Margin="0,-2,2,0"/>
                            </Border>
                        </Grid>

                        <Border BorderBrush="White" BorderThickness="1,1,0,0" Grid.ColumnSpan="3"/>
                        <Border BorderBrush="LightGray" BorderThickness="0,0,1,1" Grid.ColumnSpan="3"/>
                    </Grid>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Now that you have a new style on your view’s resource dictionary you can go ahead and set the corresponding styles in the DataGridTemplateColumn. To do so you will have to replace the Deviation Chart column on your DataGrid by a DataGridTemplateColumn:

(…)
<WpfToolkit:DataGridTemplateColumn
    Header="Deviation Chart" Width="1*"
    HeaderStyle="{StaticResource CenterAlignedColumnHeaderStyle}"
    CellStyle="{StaticResource BarChartCellStyle}"/>
(…)

By replacing this column we gave our DataGrid a much cooler look. For each player an age chart is displayed on the right:

WpfToolkitDataGrid-ss015

You can download a working sample of this code by following this link.

Grouping rows using ItemsControl.GroupStyle

From the beginning of this series we have displayed data that was supposed to be grouped. As you have noticed there are two teams and several players per team. A team should not be displayed as a regular row on our DataGrid, it should be some sort of group header that we can collapse and expand as required, showing the players that are part of it.

In this implementation we will follow the recommendations on how to do grouping on WPF Toolkit’s DataGrid.

For you to be able to do grouping you will have to create a CollectionViewSource and specify by which field the grouping will be done. In this case grouping will be done on each player’s Parent field, which corresponds to the actual Team instance.

<CollectionViewSource x:Key="PlayerData">
    <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="Parent"/>
    </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

Note that Source is not specified for the CollectionViewSource. This is due to the fact that the list is being created in code behind; as a consequence, it cannot be instantiated in xaml. You will have to set the Source for this collection after building the players list on the code behind file:

var dataProvider = (CollectionViewSource)FindResource("PlayerData");
dataProvider.Source = playerAges;

After setting up this grouped collection view source you will have to change the way binding is done on the DataGrid. Previously we were binding to a field on our view model. Now you will have to bind to a static resource.

(…)
<WpfToolkit:DataGrid
    ItemsSource="{Binding Source={StaticResource PlayerData}}"
    HorizontalScrollBarVisibility="Hidden" SelectionMode="Extended"
    CanUserAddRows="False" CanUserDeleteRows="False"
    CanUserResizeRows="False" CanUserSortColumns="False"
    AutoGenerateColumns="False"
    RowHeaderWidth="17" RowHeight="25">
(…)

The only thing left is for you to create the style of the group’s header. An expander will be used to present the grouped data. On the expander’s header each team’s name will be displayed:

<Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type GroupItem}">
                <Expander IsExpanded="True"
                          Background="{StaticResource GroubHeaderBackgroundBrush}"
                          Foreground="{StaticResource DefaultControlForegroundBrush}">
                    <Expander.Header>
                        <TextBlock Text="{Binding Name.Name}"/>
                    </Expander.Header>
                    <ItemsPresenter />
                </Expander>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Now that everything is in place you have to setup the DataGrid to use this specific style when rendering the groups:

<WpfToolkit:DataGrid.GroupStyle>
    <GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}">
        <GroupStyle.Panel>
            <ItemsPanelTemplate>

                <WpfToolkit:DataGridRowsPresenter/>
            </ItemsPanelTemplate>
        </GroupStyle.Panel>
    </GroupStyle>
</WpfToolkit:DataGrid.GroupStyle>

After these changes this is how our DataGrid is looking:

WpfToolkitDataGrid-ss016

If you click on a group header so that it collapses its contents this is how it will look:

WpfToolkitDataGrid-ss017

This implementation works well when you do not allow editing on you cells. If you allow the users to edit something on your DataGrid you will notice that the edited value goes to the bottom of the list instead of remaining in its actual row. The following screenshot is the outcome of editing the age of John Smith. Notice that John was on top and is now presented at the bottom of the Alpha Team player list.

WpfToolkitDataGrid-ss018

Our grouped data is being handled by ListCollectionView. I took a peek on the code for ListCollectionView using Reflector and found out that the source of this problem is that when you edit an item the item is resorted for grouping purposes like follows:

public void CommitEdit()
{
(…)
        if (this.IsGrouping)
        {
            this.RemoveItemFromGroups(item);
            this.AddItemToGroups(item);
        }
(…)
}

BAAM! Obviously that by removing and adding the item back again to the list will cause the item to be presented last. Not only does this affect the order of our list –which is not the intended result – it also deselects the row we are working with (I confess I did not take the time to see this through, I was short on time to finish up what I was working on time, thus the workaround presented on the following subject).

You can download a working sample of this code by following this link.

Fake grouping with the help of the ViewModel

The grouping method previously demonstrated, although of clear implementation, has several issues that could not be easily fixed. In my application I ended up using another method for grouping data, a more archaic method but will allow us greater control over how data behaves.

The actual grouping of data will be our view model’s responsibility. Group headers will be authentic rows but with a different style. The logic for hiding or showing rows accordingly to their groups being expanded or not will be controlled by the view model through data binding.

In the PlayerAge class – the data behind each row – there is a field named IsExpanded that is only set on Parent rows (the teams). We can control if the child rows are collapsed or not by adding a DataTrigger that binds to the IsExpanded property of the Parent row for each player.

There will be two different control templates: one for players and one for teams. You will have to create a new style for your DataGridRows. By default you will set the ControlTemplate to be the one regarding the Players:

<ControlTemplate TargetType="{x:Type WpfToolkit:DataGridRow}">
    <Border x:Name="DGR_Border"
            Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            SnapsToDevicePixels="True">
        <WpfToolkit:SelectiveScrollingGrid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <WpfToolkit:DataGridCellsPresenter
                Grid.Column="1"
                ItemsPanel="{TemplateBinding ItemsPanel}"
                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
            <WpfToolkit:DataGridDetailsPresenter
                WpfToolkit:SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding
                    RelativeSource={RelativeSource AncestorType={x:Type WpfToolkit:DataGrid}},
                    Path=AreRowDetailsFrozen,
                    Converter={x:Static WpfToolkit:DataGrid.RowDetailsScrollingConverter},
                    ConverterParameter={x:Static WpfToolkit:SelectiveScrollingOrientation.Vertical}}"
                Grid.Column="1" Grid.Row="1"
                Visibility="{TemplateBinding DetailsVisibility}" />
            <WpfToolkit:DataGridRowHeader
                WpfToolkit:SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"  Grid.RowSpan="2"
                Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type WpfToolkit:DataGrid}},
                    Path=HeadersVisibility,
                    Converter={x:Static WpfToolkit:DataGrid.HeadersVisibilityConverter},
                    ConverterParameter={x:Static WpfToolkit:DataGridHeadersVisibility.Row}}"/>
        </WpfToolkit:SelectiveScrollingGrid>
    </Border>
    <ControlTemplate.Triggers>
        <DataTrigger Binding="{Binding Parent.IsExpanded}" Value="False">
            <Setter TargetName="DGR_Border" Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

The most important part of this ControlTemplate is the DataTrigger on the bottom. Has you can see we set the visibility of our row based on if the parent is expanded or not.

Now you will have to add a new ControlTemplate for the parent rows (teams). For this purpose you will have to set a DataTrigger on your Style that checks whether the Parent of the bounded item is null or not – indicating that it is a parent, or not (for the complete style please see the sample code for this post).

<Style.Triggers>
    <DataTrigger Binding="{Binding Parent}" Value="{x:Null}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type WpfToolkit:DataGridRow}">
                    <Border x:Name="DGR_Border"
                            Background="{StaticResource GroubHeaderBackgroundBrush}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            SnapsToDevicePixels="True">
                        <WpfToolkit:SelectiveScrollingGrid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>

                            <WpfToolkit:DataGridCellsPresenter
                                Grid.Column="1"
                                Background="Red"
                                ItemsPanel="{TemplateBinding ItemsPanel}"
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            <WpfToolkit:DataGridDetailsPresenter
                                WpfToolkit:SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding
                                    RelativeSource={RelativeSource AncestorType={x:Type WpfToolkit:DataGrid}},
                                    Path=AreRowDetailsFrozen,
                                    Converter={x:Static WpfToolkit:DataGrid.RowDetailsScrollingConverter},
                                    ConverterParameter={x:Static WpfToolkit:SelectiveScrollingOrientation.Vertical}}"
                                Grid.Column="1" Grid.Row="1"
                                Visibility="{TemplateBinding DetailsVisibility}" />
                            <WpfToolkit:DataGridRowHeader
                                WpfToolkit:SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
                                Grid.RowSpan="2"
                                Visibility="{Binding RelativeSource={RelativeSource
                                    AncestorType={x:Type WpfToolkit:DataGrid}},
                                    Path=HeadersVisibility,
                                    Converter={x:Static WpfToolkit:DataGrid.HeadersVisibilityConverter},
                                    ConverterParameter={x:Static WpfToolkit:DataGridHeadersVisibility.Row}}"/>
                        </WpfToolkit:SelectiveScrollingGrid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </DataTrigger>
</Style.Triggers>

The ControlTemplate’s trigger was removed given that this row is a parent and will not collapse. After inserting this new style for DataGridRows on the view’s resource dictionary, you will immediately see the result, were group headers display different from other cells. The problem is that we still have not implemented a mechanism that allows us to modify the expanded state of the group.

An example on how to control the IsExpanded state of your team is to create a specific CellStyle for the first column that by knowing which type of row it is binding to will display a toggle button that allows the user to expand or collapse the group:

<Style x:Key="FirstColumnCellStyle" TargetType="{x:Type WpfToolkit:DataGridCell}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type WpfToolkit:DataGridCell}">
                <Grid Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="Right"
                                      VerticalAlignment="Center" Margin="0,0,4,0" />
                </Grid>
                <ControlTemplate.Triggers>
                    <DataTrigger Binding="{Binding ToleranceState}"
                                 Value="NotToleranced">
                        <Setter Property="IsEnabled" Value="False" />
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <DataTrigger Binding="{Binding Parent}" Value="{x:Null}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type WpfToolkit:DataGridCell}">
                        <Grid Background="{TemplateBinding Background}">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <ToggleButton VerticalAlignment="Center"
                                          IsChecked="{Binding IsExpanded}"
                                          Height="12" Width="12" Content="+" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </DataTrigger>
    </Style.Triggers>
</Style>

By now you will be able to expand or collapse each team’s players. This is how the DataGrid looks when these styles get applied.

WpfToolkitDataGrid-ss019

Now when you run the sample you can edit any cell and see that it does not change. I have kept the same style for the header rows but you can easily change it so that no cells are rendered on it, you could even make it look like the one on the previous topic using an expander.

You can download a working sample of this code by following this link.

End of Part IV

In this part we have delve into more advanced concepts. We have seen how to work around the issue with binding and the DataGridComboBoxColumn. We also saw the amazing power and flexibility of the DataGridTemplateColumn. The second half of the blog post walked you through two different methods of grouping data within the DataGrid.

By now, and assuming you have gone through all the IV parts, you should be able to represent any type of data as you see fit.

From → WPF

103 Comments
  1. I see a lot of interesting content on your website. You have to spend a lot of
    time writing, i know how to save you a lot of time, there is a tool that creates unique, SEO friendly posts in couple of seconds, just search in google – laranita’s free content
    source

  2. Hey there are using WordPress for your site platform?
    I’m new to the blog world but I’m trying to get started and create my
    own. Do you need any coding expertise to make your own blog?
    Any help would be really appreciated!

  3. arifien permalink

    hi Samuel Moura,
    i have a problem on my datagridComboBox.?please help me.

    just like ur program above:
    “WPF Toolkit DataGrid Sample 12 – ComboBoxes and DataGridTemplateColumn”

    i would like to ask can u set a dynamic value on your comboBox,
    as shown above in Category field u have a list of data.

    i want a dynamic value in comboBox list.
    please help me to construct it.

    thanks,

  4. Vishal Borude permalink

    Sir, Please guide me , how to prevent duplicate selection of datagridcomboboxcolumn in datagrid row. And also how i can compare some text with datagridcomboboxcolumn text.

    Please if you got solution send me on vishalborude28@gmail.com

  5. Aaron permalink

    Samuel, your example to do grouping is very helpful. I am trying to figure out how to hide some of the columns on the parent rows. Do you have and ideas on this?

    Aaron

  6. saurav permalink

    how to do it with double hierarchy i.e. parent inside parent….

  7. Hugo permalink

    Hi Samuel,

    Thanks a lot for this tutorial, it is seriously helpful!
    I am developing an application, and I have figured out how I can use this datagrid.

    However, I would like to change 2 things, that would make it perfect!

    - I want to be able to select/deselect every one in a team,using for example a seperate checkbox.
    - I would like to (de)select team members using only own mouseclick.
    (now i need two, one to select the row, own to check/uncheck)

    You or anyone encountered such a thing already ? And if so, maybe share some insight how to do this ?

  8. Hugo permalink

    Hi Samuel,

    Thanks a lot for this tutorial, it is seriously helpful!
    I am developing an application, and I have figured out how I can use this datagrid.

    However, I would like to change 2 things, that would make it perfect!

    - I want to be able to select/deselect every one in a team,using for example a seperate checkbox.
    - I would like to (de)select team members using only own mouseclick.
    (now i need two, one to select the row, own to check/uncheck)

    You or anyone encountered such a thing already ?

    Hugo Andrioli

  9. kishore permalink

    Excellent InDepth article will suite to any kind of learner.

  10. Antonio permalink

    About Grouping with ViewModel:
    Hello Samuel, I’ve a problem about ViewModel.

    When I go to insert a new PlayerAge as a child of “alphateam” It goes to the bottom and it seems to be not a child of “alphateam”. Then when I collapse it everithing seems to work well, but when I re-expand the “alphateam” (the new item) goes always to the bottom.

    Have you any suggestion?

    Thanks a lot

  11. Baye permalink

    Nice aerticel but something isn’t clear for me for the DataTrigger binding property value you set the value to be “Both” What is “Both” ? Is that built in value?

  12. Nico permalink

    Thank you for the example. I switched your project to .net 4.0 – there the bug with edited lines on the bottom of the group is fixed.

    Nico

  13. Yazid permalink

    Nice article, how do I get the horizontal scrollbar to appear?

  14. FastLearner permalink

    Hi,
    I have the same issue “a row updated goes to the bottom of the group”.
    I am using datasets,datatables and list collection view.
    Here is the code that i have written

    ListCollectionView view = null;
    ICollectionView gridView = null;

    this.sdaExt.Fill(this.dsExt.dtext);
    view = new ListCollectionView(this.dsExt.dtext.ToList());
    view.GroupDescriptions.Add(new PropertyGroupDescription(“extNm”));
    this.gridView = CollectionViewSource.GetDefaultView(view);
    this.DataContext = this.gridView;

    How can i change this code to stop the row being edited from moving downwards.

  15. Alpe permalink

    The right code fragment:

    <Style TargetType="DataGridRow">
    <Style.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Yellow"/>
    </Style.Resources>

  16. Alpe permalink

    @sportscrazy
    Yes, there is a default brush which must overritten for the selcetion style:

  17. NewDeveloper permalink

    How do i work around the fact that the row that i am updating goes to the bottm of the group?

  18. Grouping is accomplished by filtering out rows by their Parent property. In order for you to group them you will have to set the Parent on each new row to whatever value you need.

  19. juandix permalink

    First of all Samuel I would like to thank you for this superb tutorial and the example code provided (specially Sample 15).
    I would like to ask you something I have not been able to resolve by myself, still new with WPF. I am busy with an application of your Sample 15 and I have been able to get my application working perfectly except for one detail. The problem is when I insert a new object in the ObservableCollection in my ViewModel this change is reflected perfectly but the feature to hide it when clicking the parent is gone. Everything will hide except such elements inserted after mine grid is already instantiated. I hope you can give me some insight to solve this. I appreciate your help. Thanks in advance.

Trackbacks & Pingbacks

  1. WPFToolkit Grid formatting with dynamic columns « Dev Station 971
  2. Dew Dump – June 18, 2009 | Alvin Ashcraft's Morning Dew
  3. Dew Dump – June 17, 2009 | Alvin Ashcraft's Morning Dew
  4. DotNetShoutout

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS