如何单击嵌套在数据网格内的数据网格中的复选框

Posted

技术标签:

【中文标题】如何单击嵌套在数据网格内的数据网格中的复选框【英文标题】:How to single click checkbox in datagrid nested inside a datagrid 【发布时间】:2017-05-27 00:13:27 【问题描述】:

我几乎用谷歌搜索到了这个。我看到了很多解决我的问题的方法,但它们都不起作用......我只能假设这是因为我在中心嵌套了带有复选框的数据网格。现在我的应用需要点击两次来更改复选框的选中状态。我假设第一次点击是关注适当的行?或单元格,第二次单击激活检查状态更改。

这是我的 XAML:

<Grid>
    <DockPanel ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" VirtualizingPanel.IsContainerVirtualizable="True" >
        <TextBox x:Name="textBoxSearch" DockPanel.Dock="Top" Margin="10" TextChanged="TxtFilter_TextChanged" Height="25" MinWidth="250" HorizontalAlignment="Stretch"/>
        <DataGrid x:Name="objDatagrid" ItemsSource="Binding DataView" CanUserAddRows="False" CanUserDeleteRows="False" AutoGenerateColumns="False"
              HeadersVisibility="None" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDetailsVisibilityMode="Visible"
                  VirtualizingPanel.VirtualizationMode="Recycling">
            <DataGrid.GroupStyle>
                <!-- Style for groups at top level. -->
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style TargetType="x:Type GroupItem">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="x:Type GroupItem">
                                        <Expander Margin="15 0 15 0" IsExpanded="True" HorizontalAlignment="Stretch">
                                            <Expander.Header>
                                                <!-- Control for the expander header text -->
                                                <custom:HighlightTextBlock Text="Binding Path=Name" 
                                                                             HighlightPhrase="Binding ElementName=textBoxSearch, Path=Text"
                                                                             HighlightBrush="Lime"/>
                                            </Expander.Header>
                                            <ItemsPresenter HorizontalAlignment="Stretch" />
                                        </Expander>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
            </DataGrid.GroupStyle>
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <!-- Question Container Textblock. -->
                            <custom:HighlightTextBlock Text="Binding QuestionText" FontWeight="Bold"
                                                         HighlightPhrase="Binding ElementName=textBoxSearch, Path=Text"
                                                         HighlightBrush="Lime"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
            <DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <DataGrid x:Name="objInnerDatagrid" ItemsSource="Binding Answers" CanUserAddRows="False" CanUserDeleteRows="False"
                              HeadersVisibility="None" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                              AutoGenerateColumns="False">

                        <DataGrid.Columns>
                            <DataGridTemplateColumn>
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <DockPanel>
                                            <CheckBox DockPanel.Dock="Top" Checked="CheckBox_Checked" Unchecked="CheckBox_Checked" IsChecked="Binding Path=IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged">
                                                <CheckBox.Content>
                                                    <!-- Answer Checkbox Content : Textblock. -->
                                                    <custom:HighlightTextBlock Text="Binding AnswerText"
                                                                             HighlightPhrase="Binding ElementName=textBoxSearch, Path=Text" HighlightBrush="Lime"/>
                                                </CheckBox.Content>
                                            </CheckBox>
                                            <custom:TestUC Margin="20,10,0,0" HorizontalAlignment="Stretch" Visibility="Collapsed" x:Name="SubQuestionUserControl"/>

                                        </DockPanel>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
                        </DataGrid.Columns>
                    </DataGrid>
                </DataTemplate>
            </DataGrid.RowDetailsTemplate>
        </DataGrid>
    </DockPanel>
</Grid>

我尝试过设置样式:

 <UserControl.Resources>
    <vm:StringToVisibilityConverter x:Key="StringToVisibilityConverter"/>
    <BooleanToVisibilityConverter x:Key="BoolToVisibility"/>
    <!--<Style TargetType="custom:DataGridWithNavigation" BasedOn="StaticResource x:Type DataGrid"/>-->
    <!--<Style TargetType="x:Type DataGridCell">
        <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown" />
        <EventSetter Event="PreviewTextInput" Handler="DataGridCell_PreviewTextInput" />
    </Style>-->
    <!--<Style x:Key="dataGridStyle" TargetType="x:Type DataGridCell">
        <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown"></EventSetter>
    </Style>-->
    <!--<Style TargetType="x:Type DataGridRow">
        <EventSetter Event="MouseEnter" Handler="DataGridCell_PreviewMouseLeftButtonDown"></EventSetter>
    </Style>-->
    <!--<Style TargetType="DataGridRow">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="IsSelected" Value="True" />
            </Trigger>
        </Style.Triggers>
    </Style>-->
    <!--<Style TargetType="DataGridCell">
        <Style.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsReadOnly" Value="False" />
                    <Condition Property="IsMouseOver" Value="True" />
                </MultiTrigger.Conditions>
                <Setter Property="IsEditing" Value="True" />
            </MultiTrigger>
        </Style.Triggers>
    </Style>-->
</UserControl.Resources>

不幸的是,我不再拥有显示任何相关事件的代码。

我也尝试在这里使用某人的自定义数据网格类引用: https://***.com/a/4827377/5807358

这个自定义类让我最接近。事实上它工作得很好......直到我需要取消选中该复选框(位于内部数据网格中)。如果不先切换到主数据网格的另一行然后再返回,就无法更改已选中框的选中状态。我试图进一步定制该课程以获得我想要的东西,但没有完成。

我还应该注意,我已经尝试了上面发布的 *** 链接上的所有解决方案。

以前有人遇到过这种情况吗?如果有人认为它相关,我可以发布我的代码隐藏。

谢谢

【问题讨论】:

【参考方案1】:

我在这里找到了答案! : http://blog.ditran.net/wpf-datagrid-rowdetailstemplate-double-click-focus-fix/

我会发布代码以防帖子被删除:

<DataGrid.RowStyle>
                <Style TargetType="x:Type DataGridRow">
                    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="SelectRowDetailSection"/>
                </Style>
</DataGrid.RowStyle>

事件处理程序:

void SelectRowDetailSection(object sender, MouseButtonEventArgs e)
    
        var row = sender as DataGridRow;
        if (row != null)
        
            row.Focusable = true;
            row.Focus();
            // Creating a FocusNavigationDirection object and setting it to a
            // local field that contains the direction selected.
            FocusNavigationDirection focusDirection = FocusNavigationDirection.Next;
            // MoveFocus takes a TraveralReqest as its argument.
            TraversalRequest request = new TraversalRequest(focusDirection);
            // Gets the element with keyboard focus.
            UIElement elementWithFocus = Keyboard.FocusedElement as UIElement;
            // Change keyboard focus.
            if (elementWithFocus != null)
            
                elementWithFocus.MoveFocus(request);
            
        
    

上面的样式需要添加到外部。当我将它添加到 UserControl.Resources 部分时,它什么也没做。 我应该注意到我必须向 DataGridRow 添加一个额外的样式。使用上面的代码选择行时,行标题消失。这很可能是由我这边的某些事情引起的。我正在使用 mahapps.metro 来设计我的窗户。我敢打赌这可能是罪魁祸首。

【讨论】:

以上是关于如何单击嵌套在数据网格内的数据网格中的复选框的主要内容,如果未能解决你的问题,请参考以下文章

如何创建一个道场数据网格,其中一列是标题行中的按钮?

KivyMD RecycleView 网格中的复选框操作重复

如何让复选框在 WPF 数据网格中工作

复选框上的多行选择和单击 MUI DataGrid 中的行时的单选

增强网格中的行选择

数据网格复选框自动化