我差点用谷歌将自己逼死。我看到了很多解决问题的方法,但是它们都没有用……我只能认为是因为我将数据网格嵌套在复选框的中央。现在,我的应用程序需要单击两次才能更改复选框的检查状态。我认为第一次单击是为了将注意力集中在适当的行上?或单元格,然后单击第二次激活检查状态更改。
这是我的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>
不幸的是,我不再需要任何相关事件的代码了。
我也尝试过在这里使用某人的自定义datagrid类引用:
https://stackoverflow.com/a/4827377/5807358
这个自定义类使我最接近。实际上,它工作得很好……直到我需要取消选中该复选框(位于内部数据网格中)。如果不先切换到主数据网格的另一行再返回,就无法更改已选中复选框的检查状态。我在尝试进一步自定义该类以获得自己想要的东西的过程中摆弄着东西,但结果却很短。
我还应该注意,我已经在上面发布的stackoverflow链接上尝试了所有解决方案。
有人遇到过吗?如果有人认为它与代码相关,则可以将其隐藏在代码后面。
谢谢
最佳答案
我在这里找到了答案! :
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设置窗口样式。我打赌这可能是罪魁祸首。
关于c# - 如何单击嵌套在数据网格中的数据网格中的复选框,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41603843/