DataGrid RowDetails Selection

882 views Asked by At

I have a DataGrid which has its RowDetailsTemplate set to a ListBox. I have set the DataGridRowHeaderStyle as a ToggleButton as below:

<Style x:Key="DataGridRowHeaderStyle" TargetType="{x:Type DataGridRowHeader}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="36"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        <Border x:Name="bd" BorderBrush="Black" BorderThickness="1,0.5,1,1" Height="36" Width="20" HorizontalAlignment="Stretch"
                            VerticalAlignment="Stretch" Margin="0" >
                            <ToggleButton Style="{StaticResource RowDetailExpanderWithPlusSymbol}" 
                                          Visibility="{Binding Converter={StaticResource RowDetailsVisibilityConverter}}" 
                                          Click="ToggleButton_Click"
                                          MouseDoubleClick="ToggleButton_MouseDoubleClick">
                                <!--<ToggleButton.CommandParameter>
                                    <MultiBinding Converter="{StaticResource SelectedCodesMultiBindingConverter}">
                                        <Binding Path="."/>
                                        <Binding RelativeSource="{RelativeSource Self}" Path="IsChecked"/>
                                    </MultiBinding>
                                </ToggleButton.CommandParameter>-->
                                <ToggleButton.IsChecked>
                                    <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}" Path="DetailsVisibility" Mode="TwoWay"  >
                                        <Binding.Converter>
                                            <infConv:DetailsVisibilityToBool FalseToVisibility="Collapsed" />
                                        </Binding.Converter>
                                    </Binding>
                                </ToggleButton.IsChecked>
                            </ToggleButton>
                        </Border>
                        <Border Grid.Row="1" VerticalAlignment="Stretch"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

I am selecting the DataGridRow when I click the DataGridRowHeader toggle button as below:

 private void ToggleButton_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            ToggleButton tg = sender as ToggleButton;
            UiUser user = tg.DataContext as UiUser;
            DataGridRow dr = dg.ItemContainerGenerator.ContainerFromItem(user) as DataGridRow;
            dr.IsSelected = true;
            dr.Focus();
        }
        catch (Exception ex)
        {

        }
    }

What I want is that the next time I select the ListBox item it should be selected and be active. However I have to click it two times to get make it active. Kindly Help.

EDIT - RowDetailsTemplate:

 <DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <ContentControl DataContext="{Binding}">
                <ListBox x:Name="lBox" ItemsSource="{Binding Similar}">
                    <ListBox.ItemContainerStyle>
                        <Style TargetType="{x:Type ListBoxItem}">
                            <Style.Resources>
                                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Blue"/>
                                <!-- Background of selected item when focussed -->
                                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Blue"/>
                                <!-- Background of selected item when not focussed -->
                                <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="LightGray" />
                            </Style.Resources>
                            <!--<EventSetter Event="PreviewMouseDown" Handler="lBoxItem_PreviewMouseDown"/>-->
                            <EventSetter Event="MouseDoubleClick" Handler="LBox_MouseDoubleClick_Inside"/>
                            <Style.Triggers>
                                <Trigger Property="IsSelected" Value="True">
                                    <Setter Property="Background" Value="Blue"/>
                                </Trigger>
                            </Style.Triggers>

                        </Style>
                    </ListBox.ItemContainerStyle>
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal" >

                                <Border Margin="-3,-3,0,0" BorderBrush="Gray" Width="{Binding ElementName=NameDataGridColumn, Path=ActualWidth}" BorderThickness="1,0,0,1">
                                    <TextBlock ToolTip="{Binding person, Converter={StaticResource FormattedNameConverter}}" Margin="5,0,0,0" TextTrimming="CharacterEllipsis"
                                               Text="{Binding InternalUser.person, Converter={StaticResource FormattedNameConverter}}" VerticalAlignment="Center">
                                    </TextBlock>
                                </Border>

                                <Border Margin="0,0,0,0" BorderBrush="Gray" Width="{Binding ElementName=OrgDataGridColumn, Path=ActualWidth}" BorderThickness="1,0,0,1">
                                    <TextBlock  HorizontalAlignment="Stretch" TextTrimming="CharacterEllipsis" ToolTip="{Binding Path=organizationsString}"
                                    Text="{Binding Path=organizationsString}"
                                    Margin="5,0,0,0" VerticalAlignment="Center"/>
                                </Border>

                                <Border Margin="0,0,0,0" BorderBrush="Gray" Width="{Binding ElementName=RolesDataGridColumn, Path=ActualWidth}" BorderThickness="1,0,0,1">
                                    <TextBlock HorizontalAlignment="Stretch" Margin="5,0,0,0"
                                Text="{Binding Path=rolesString}" ToolTip="{Binding Path=rolesString}"
                                TextTrimming="CharacterEllipsis" VerticalAlignment="Center" 
                                ToolTipService.Placement="Bottom" />
                                </Border>

                                <Border Margin="0,0,0,0" BorderBrush="Gray" Width="{Binding ElementName=NPIDDataGridColumn, Path=ActualWidth}" BorderThickness="1,0,0,1">
                                    <TextBlock HorizontalAlignment="Stretch"
                                       Text="{Binding InternalUser.npid}" ToolTip="{Binding InternalUser.npid}" TextTrimming="CharacterEllipsis" Margin="5,0,0,0" VerticalAlignment="Center"/>
                                </Border>

                                <Border Margin="0,0,0,0" BorderBrush="Gray" Width="{Binding ElementName=EmailDataGridColumn, Path=ActualWidth}" BorderThickness="1,0,0,1">
                                    <TextBlock Text="{Binding InternalUser.principal.user_name}" ToolTip="{Binding InternalUser.principal.user_name}" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"/>
                                </Border>

                                <Border Margin="0,0,0,0" BorderBrush="Gray" Width="{Binding ElementName=Status, Path=ActualWidth}" BorderThickness="1,0,0,1">
                                    <TextBlock Text="{Binding ActiveStatus}" ToolTip="{Binding ActiveStatus}" Padding="4,0,0,0" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" />
                                </Border>

                                <Border Margin="0,0,0,0" BorderBrush="Gray" Width="{Binding ElementName=DMUserName, Path=ActualWidth}" BorderThickness="1,0,0,1">
                                    <TextBlock  Text="{Binding InternalUser.directMailAccountId}" 
                                VerticalAlignment="Center" TextTrimming="CharacterEllipsis"
                                ToolTip="{Binding InternalUser.directMailAccountId}"/>
                                </Border>

                                <Border Margin="0,0,0,0" BorderBrush="Gray" Width="{Binding ElementName=DMAccountStatus, Path=ActualWidth}" BorderThickness="1,0,0,1">
                                    <TextBlock Margin="5,0,0,0" Text="{Binding DMStatus}" 
                               HorizontalAlignment="Stretch" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" 
                               ToolTip="{Binding DMStatus}"/>
                                </Border>
                            </StackPanel>
                        </DataTemplate>

                    </ListBox.ItemTemplate>
                </ListBox>
            </ContentControl>
        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
1

There are 1 answers

0
ttmask On

I had the same problem: There is a DataGrid, and each row has a RowDetails - RowDetailsTemplate consists of two ListBoxes. ListBoxItem is a ToggleButton. So, I wanted to select toggle button by the first click. First I founded this http://wpf.codeplex.com/wikipage?title=Single-Click%20Editing . so, I updated my ListBox`s style

 <Style x:Key="MyListBoxStyle" BasedOn="{StaticResource ToggleButtonListBoxStyle}" TargetType="{x:Type ListBox}">
        <Setter Property="ItemContainerStyle">
            <Setter.Value>
                <Style TargetType="{x:Type ListBoxItem}">
                    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBoxItem_PreviewMouseLeftButtonDown"></EventSetter>
                </Style>
            </Setter.Value>
        </Setter>

And in CodeBehind :

private void ListBoxItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var item = sender as ListBoxItem;
        if (item != null)
        {
            var toggleButton = WpfUiHelper.FindVisualChild<ToggleButton>(item);

            if (toggleButton != null)
            {
                if (toggleButton.IsChecked == false) toggleButton.IsChecked = true;
                else toggleButton.IsChecked = false;
                e.Handled = true;
            }
        }
    }

And now when I clicks at toggle button in RowDetails for the fitst time - it selects or deselects.

Hope it will help.