Home Forums WPF controls Xceed DataGrid for WPF Master-Detail hide expander on empty details section

Tagged: 

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • B.O.B.
    Participant
    Post count: 5
    #50425 |

    I’m binding to a BindingList to a class that has a child BindingList for the details that show up in my Master-Detail grid.

    Based on records in the user’s DB, some of master records don’t have any child records. I’ve searched high & low trying to figure out a way to hide or disable the expander when the master has no child rows.

    I’ve provided my own Collapse/ExpandGroupGlyph (see XAML below) – it’d be great if I could somehow add binding to the Visibility property that somehow bound to the current row has child items or not.

    I tried the following: https://xceed.com/forums/topic/expander-visibility-issue/ – but there doesn’t seem to be a HasChildItems of the DataRow.

    I tried pasting in the XAML using the code button, it won’t let me submit.

    B.O.B.
    Participant
    Post count: 5

    XAML code with the less than/greater than chars replaced with html codes:

                        <g:TableView.ExpandGroupGlyph>
                            <DataTemplate>
                                <!--  Not sure why the wonkiness, but getting the icon centered required a weird margin + wrapper grid.  -->
                                <Grid x:Name="grd"
                                      Width="24"
                                      VerticalAlignment="Stretch"
                                      Background="Transparent">
                                    <Grid.Effect>
                                        <DropShadowEffect BlurRadius="0"
                                                          RenderingBias="Performance"
                                                          ShadowDepth="1" />
                                    </Grid.Effect>
                                    <Border x:Name="brd"
                                            Width="16"
                                            Height="16"
                                            Margin="3,12"
                                            VerticalAlignment="Center"
                                            BorderBrush="LightGray"
                                            BorderThickness="1">
                                        <Border.Style>
                                            <Style>
                                                <Style.Triggers>
                                                    <DataTrigger Binding="{Binding ElementName=grd,
                                                                                   Path=IsMouseOver}"
                                                                 Value="True">
                                                        <Setter Property="Border.Background"
                                                                Value="{DynamicResource appIconColor}" />
                                                    </DataTrigger>
                                                </Style.Triggers>
                                            </Style>
                                        </Border.Style>
                                        <Path Width="10"
                                              Height="10"
                                              Margin="1"
                                              Data="M0,5 H10 M5,5 V10Z"
                                              Stroke="White"
                                              StrokeThickness="2" />
                                    </Border>
                                </Grid>
                            </DataTemplate>
                        </g:TableView.ExpandGroupGlyph>
    B.O.B.
    Participant
    Post count: 5

    I made a little progress on this one. I added a readonly property called HasChildRows to master item class that returns true if the count of the child binding list > 0.

    I then was able to use FindAncestor and bind to the parent DataRow.DataContext.HasChildRows. This works, technically.

                                      Visibility="{Binding Mode=OneWay,
                                                           RelativeSource={RelativeSource Mode=FindAncestor,
                                                                                          AncestorType={x:Type g:DataRow}},
                                                           Path=DataContext.HasChildRows,
                                                           Converter={StaticResource BooleanToVisibilityConverter}}"

    ^ the problem with the above is at runtime, Visual Studio has a silent binding error for every new row that gets loaded:

    System.Windows.Data Error: 4 : Cannot find source for binding with reference ‘RelativeSource FindAncestor, AncestorType=’Xceed.Wpf.DataGrid.DataRow’, AncestorLevel=’1”. BindingExpression:Path=DataContext.HasChildRows;

    ^ So it looks like binding is failing (at least at first) then succeeding. Is there a better way to bind so it isn’t failing at first. I’m just worried about performance if there is a bunch of rows from the master table are returned in query and every single row is going to initially fail it’s binding.

    Diane [Xceed]
    Moderator
    Post count: 1353

    Hi B.O.B.,

    To hide the details’ toggle button when the master has no details, you would have to redefine the DataRow’s ControlTemplate and hide the detailsToggleButton based on the DataRow’s HasChildItems property. In here you would have to handle the click event of your toggle button and redefine the template accordingly.

    The reason why the datagrid isn’t able to do it automatically, is because the datagrid doesn’t know about the details in advance. It doesn’t know if there are child elements or not, because it’s only when the expand button is clicked that the detail data source is actually created.

    You can use one of our Row templates found in our included theme files. Default location:
    C:\Program Files (x86)\Xceed\Xceed DataGrid for WPF v#.#\Themes

    For example, the “tableflowViewRowTemplate” control template found in the following file:
    C:\Program Files (x86)\Xceed\Xceed DataGrid for WPF v#.#\Themes\Aero\TableflowView.Aero.normalcolor.xaml

    Example of a click handler to expand/collapse the selected item:

    
      private void detailsToggle_Click(object sender, RoutedEventArgs e)
      {
          var selectedItem = this.PeopleGrid.SelectedItem;
          if (selectedItem != null)
          {
            if (expanded)
            {
                PeopleGrid.CollapseDetails(selectedItem);
                expanded = false;
            }
            else if (!expanded)
            {
                PeopleGrid.ExpandDetails(selectedItem);
                expanded = true;
            }
          }
      }
    cosmin
    Participant
    Post count: 1

    hello,

    I am joining this thread because I am interested also in an easier solution than the recommended one.

    Answer from xceed: DataGrid cannot do this because it doesn’t know when it has sub items ( loaded at click )

    BUT, we, as programmers, know that ( or it is trivially simple to add a boolean property to our VM to indicate if it has or not.

    So, what I will recommend is to expose from DataRow a Bindable property (bool) and show or hide the offending + automatically. If no Binding is set via xaml, work as it is today. So it will not disturb anybody.

    This will take xceed 1 HR of work, and make us very happy, instead of retemplating the whole DataRow only for that purpose.

    We like to be more programmers, and less designers, even xaml makes it easier.

    Retemplating something there anyway takes lots amount of time just to map all the colors/brushes/theming and so on.

    thank you for your understanding

Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.