Home Forums WPF controls Xceed DataGrid for WPF Group Style in TableView

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
    Posts
  • User (Old forums)
    Member
    Post count: 23064
    #21734 |

    1. Does anyone have an example of how to customize the look of the GroupHeader in TableView. I need to change how the Toggle button appears, format the text differentently and add an Image.

    2. In Windows Exporer on Vista when you group the items in the right pane, clicking on the Group Header will automatically select all the items in the Group. It also shows the Group as being selected (ie a Highlight around the Group Header itself). Does anyone know if I can mimic the same behaviour with the GroupHeader in the DataGridControl. This funcionnality is essential to a product that I am working on that is scheduled to ship in less than 2 months.

    Thanks!

    Imported from legacy forums. Posted by Ryan (had 10144 views)

    Xceed Support
    Member
    Post count: 5658

    1.

    Customization of how a GroupHeader looks can be done in two ways (and they are complementary).

    First, you can define a DataTemplate that defines how a group information is displayed… This is done by setting an implicit style for the Xceed.Wpf.DataGrid.Group type.

    <code>
    <DataTemplate DataType=”{x:Type xcdg:Group}”>

    <StackPanel Orientation=”Horizontal”>

    <ContentPresenter Content=”{Binding Title}”
    ContentTemplate=”{Binding RelativeSource={RelativeSource TemplatedParent},Path=DataContext.TitleTemplate}”
    ContentTemplateSelector=”{Binding RelativeSource={RelativeSource TemplatedParent},Path=DataContext.TitleTemplateSelector}” />

    <TextBlock Text=”: ” />

    <ContentPresenter Content=”{Binding Value}” />

    </StackPanel>
    </DataTemplate>
    </code>

    Note: Please note the “particular” binding done on ContentTemplate and ContentTemplateSelector of the first ContentPresenter, this is required because when the Binding to the Content property resolves, the DataContext of the ContentPresenter changes to the Content of the ContentPresenter…

    But this is only how a group <i>information</i> is displayed… If you want to change the way the GroupHeader itself is displayed.

    Once again, you can achieve this by setting an Implicit style on the Xceed.Wpf.DataGrid.GroupHeaderControl type:

    <code>
    <Style TargetType=”{x:Type xcdg:GroupHeaderControl}”>

    </Style>
    </code>

    You can find examples of GroupHeaderControl styles and templates in the “Xceed Components” installation directory (typically C:\Program Files\Xceed Components, if you did not change it ) under:

    “Xceed DataGrid for WPF 1.0\Themes”

    In each sub-folder there is a file called: TableView.<i>xxx</i>.<i>yyy</i>.xaml which contains resources called:

    – tableViewGroupHeaderControlTemplate (ControlTemplate for the GroupHeaderControl)
    – tableView<i>xxxyyy</i>GroupHeaderControlStyle (Style for the GroupHeaderControl)

    Imported from legacy forums. Posted by Marcus [Xceed] (had 614 views)

    Xceed Support
    Member
    Post count: 5658

    Since the code is messing up the layout of the text in Internet Explorer, I’m reposting the above post… Without the code:

    <hr>
    Customization of how a GroupHeader looks can be done in two ways (and they are complementary).

    First, you can define a DataTemplate that defines how a group information is displayed… This is done by setting an implicit style for the Xceed.Wpf.DataGrid.Group type.

    [code]

    Note: Please note the “particular” binding done on ContentTemplate and ContentTemplateSelector of the first ContentPresenter, this is required because when the Binding to the Content property resolves, the DataContext of the ContentPresenter changes to the Content of the ContentPresenter…

    But this is only how a group information is displayed… If you want to change the way the GroupHeader itself is displayed.

    Once again, you can achieve this by setting an Implicit style on the Xceed.Wpf.DataGrid.GroupHeaderControl type:

    [code]

    You can find examples of GroupHeaderControl styles and templates in the “Xceed Components” installation directory (typically C:\Program Files\Xceed Components, if you did not change it ) under:

    “Xceed DataGrid for WPF 1.0\Themes”

    In each sub-folder there is a file called: TableView.xxx.yyy.xaml which contains resources called:

    – tableViewGroupHeaderControlTemplate (ControlTemplate for the GroupHeaderControl)
    – tableViewxxxyyyGroupHeaderControlStyle (Style for the GroupHeaderControl)

    Imported from legacy forums. Posted by Marcus [Xceed] (had 557 views)

    Xceed Support
    Member
    Post count: 5658

    2.

    Unfortunatly, there is no “easy” way of doing this at the moment… I posted your suggestion as a feature request…

    While I mentionned that there was no “easy” way of doing this, I don’t think it’s impossible.

    You can create a custom RoutedCommand:

    <code>
    public static readonly RoutedCommand SelectGroupCommand =
    new RoutedCommand( “SelectGroup”, typeof( Window1 ) );
    </code>

    In the Initialization code of Window1:

    <code>
    this.CommandBindings.Add( new CommandBinding( SelectGroupCommand,
    new ExecutedRoutedEventHandler( OnSelectGroupExecuted ) ) );
    </code>

    Then, somewhere in the GroupHeaderControl’s template:

    <code>
    <StackPanel.InputBindings>
    <MouseBinding Gesture=”LeftClick”
    Command=”{x:Static local:Window1.SelectGroupCommand}” />
    </StackPanel.InputBindings>
    </code>

    Now, in the OnSelectGroupExecuted handler, you would need to:

    – using the OriginalSource property of the ExecutedEventArgs and the VisualTreeHelper, recurse in the VisualTree until find the GroupHeaderControl.

    – Search the DataGridControl.Items.Groups tree for a CollectionView group that has the same “Name” as the GroupHeaderControl.Group.Value… (note: DataGridControl.Items.Groups is built like a tree, you should take consideration of the level of the group [ Level property ] )

    – Add each element of the CollectionViewGroup.Items collection for the group you identified to the DataGridControl.SelectedItems collection.

    Imported from legacy forums. Posted by Marcus [Xceed] (had 784 views)

    User (Old forums)
    Member
    Post count: 23064

    Thank you, I will see what I can get working today.

    Imported from legacy forums. Posted by Ryan (had 608 views)

    User (Old forums)
    Member
    Post count: 23064

    I am still struggling. Here is what I am trying to do with the customization of the header. I have an observable collection of the following object:

    public class AudioFileInfo : INotifyPropertyChanged
    {
    public int AlbumId
    {
    get { return m_albumId; }
    }

    public int SongId
    {
    get { return m_songId; }
    }

    public int DeviceId
    {
    get { return m_deviceId; }
    }

    public string Path
    {
    get { return m_path; }
    }

    public string AmgId
    {
    get { return m_amgId; }
    }

    public string Album
    {
    get { return m_album; }
    }

    public string Artist
    {
    get { return m_artist; }
    }

    public string Title
    {
    get { return m_title; }
    }

    public int TrackNumber
    {
    get { return m_trackNumber; }
    }

    public string Genre
    {
    get { return m_genre; }
    }

    public string ReleaseDate
    {
    get { return m_releaseDate; }
    }

    public string RecordLabel
    {
    get { return m_recordLabel; }
    }

    public string Description
    {
    get { return m_description; }
    }

    public ImageSource Thumbnail
    {
    get { return m_thumbnail; }
    }

    }

    I want to group the collection by AlbumId.
    In the header I want to show the AlbumName of the first item in the Group, the Thumbnail of the first item in the Group, and other info related to the first item in the Group.

    With the ListView in WPF, I just did the following:

    <Style TargetType=”{x:Type GroupItem}”>
    <Setter Property=”Margin” Value=”0,0,0,5″/>
    <Setter Property=”Template”>
    <Setter.Value>
    <ControlTemplate TargetType=”{x:Type GroupItem}”>
    <Expander IsExpanded=”False”>
    <Expander.Header>
    <StackPanel Orientation=”Horizontal”>
    <Image x:Name=”img” Source =”{Binding Path=Items[0].ThumbnailUri}”/>
    <TextBlock FontWeight=”Bold” Text=”{Binding Path=Items[0].Album}”/>
    <TextBlock FontWeight=”Bold” Text=”{Binding Path=Items[0].Artist}”/>
    <TextBlock FontWeight=”Bold” Text=”{Binding Path=Items[0].Genre}”/>
    <TextBlock FontWeight=”Bold” Text=”{Binding Path=Items.Count}”/>
    </StackPanel>
    </Expander.Header>
    <Expander.Content>
    <ItemsPresenter Margin=”0,0,0,0″/>
    </Expander.Content>
    </Expander>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>

    Is there an easy way to do the same thing with the DataGridControl? I would just go back to using the ListView, but the DataGridControl is WAY FASTER! Also, is there a way to have the groups initially collapsed like my example above does?

    Thanks.

    Imported from legacy forums. Posted by Ryan (had 519 views)

    Xceed Support
    Member
    Post count: 5658

    What I can suggest you is somehow similar to how we display a relation’s information in the Solid Foundation sample…

    In the Solid Foundation Sample, we built a DataTableDictionary which associate a value (e.g. Your Album ID) with an Object (AudioFileInfo), found in a collection provided to the DataTableDictionary at its creation (see derived class EmployeeIDDictionary).

    Nothing would prevent your from creating your own AudioFileInfoDictionary based on that principle and use it in the implicit “Group” DataTemplate:

    (example code following)

    Imported from legacy forums. Posted by Marcus [Xceed] (had 608 views)

    Xceed Support
    Member
    Post count: 5658

    <code>
    <DataTemplate DataType=”{x:Type xcdg:Group}”>
    <StackPanel Orientation=”Horizontal”>
    <local:AudioFileInfoDictionary Key=”{Binding Value}”>
    <local:AudioFileInfoDictionary.ContentTemplate>
    <DataTemplate>
    <StackPanel Orientation=”Horizontal”>
    <Image x:Name=”img” Source =”{Binding Path=ThumbnailUri}”/>
    <TextBlock FontWeight=”Bold” Text=”{Binding Path=Album}”/>
    <TextBlock FontWeight=”Bold” Text=”{Binding Path=Artist}”/>
    <TextBlock FontWeight=”Bold” Text=”{Binding Path=Genre}”/>
    </StackPanel>
    </DataTemplate>
    </local:AudioFileInfoDictionary.ContentTemplate>
    </local:AudioFileInfoDictionary>
    <<TextBlock FontWeight=”Bold” Text=”{Binding Path=ItemCount}”/>
    </StackPanel>
    </DataTemplate>
    </code>

    Imported from legacy forums. Posted by Marcus [Xceed] (had 392 views)

    User (Old forums)
    Member
    Post count: 23064

    Thanks for all the help so far. I feel like I am getting close. I have done what you have suggested and created an AudioFileInfoDictionary class. I have used the DataTemplate you provided. However, I get the following errors at runtime:

    ‘ThumbnailUri’ property not found on ‘object’ ”Group’
    ‘Album’ property not found on ‘object’ ”Group’
    ‘Artist’ property not found on ‘object’ ”Group’
    ‘Genre’ property not found on ‘object’ ”Group’

    My AudioFileInfoDictionary class has those Properties. But it looks like it is trying to find those Properites on the Group object instead.

    Imported from legacy forums. Posted by Ryan (had 533 views)

    Xceed Support
    Member
    Post count: 5658

    Can you share the code for your dictionary?

    Imported from legacy forums. Posted by Marcus [Xceed] (had 374 views)

    User (Old forums)
    Member
    Post count: 23064

    I finally got it working. There was a problem with how the binding was setup in my Dictionary. However, binding the Group’s Value to the AudioFileInfoDictionary’s Key does not work for some reason. If I pass in a static value to the key it works:

    <local:AudioFileInfoDictionary Key=”200″>

    but doing a databinding does not:

    <local:AudioFileInfoDictionary Key=”{Binding Value}”>

    this also works oddly enough, and is what I am doing at the moment.

    <TextBlock x:Name=”Id” Visibility=”Collapsed” Text=”{Binding Path=Value}”/>
    <local:AudioFileInfoDictionary Key=”{Binding ElementName=Id, Path=Text}”>

    I understand there is probably just something I don’t understand about WPF databinding.

    Imported from legacy forums. Posted by Ryan (had 9338 views)

Viewing 11 posts - 1 through 11 (of 11 total)
  • You must be logged in to reply to this topic.