WPF:选中DataGridRow时如何仅显示行详情隐藏行?
实现选中行隐藏主体仅显示详情的方案
当然可以实现!这里有几种适合WPF DataGrid的解决方案,你可以根据项目情况选择:
方案1:自定义DataGridRow模板(直接XAML实现)
这种方式不需要修改ViewModel,直接通过自定义行模板来控制主体和详情的可见性:
<DataGrid ItemsSource="{Binding MyList}" AutoGenerateColumns="False" SelectionUnit="FullRow"> <!-- 自定义行样式 --> <DataGrid.RowStyle> <Style TargetType="DataGridRow"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="DataGridRow"> <Grid> <!-- 行的主体内容(默认显示) --> <ContentPresenter x:Name="RowMainContent" Visibility="Visible"/> <!-- 行详情(默认隐藏) --> <ContentPresenter x:Name="RowDetailsContent" Content="{TemplateBinding DetailsTemplate}" ContentTemplate="{TemplateBinding DetailsTemplate}" Visibility="Collapsed"/> </Grid> <!-- 触发器控制可见性 --> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter TargetName="RowMainContent" Property="Visibility" Value="Collapsed"/> <Setter TargetName="RowDetailsContent" Property="Visibility" Value="Visible"/> </Trigger> <Trigger Property="IsSelected" Value="False"> <Setter TargetName="RowMainContent" Property="Visibility" Value="Visible"/> <Setter TargetName="RowDetailsContent" Property="Visibility" Value="Collapsed"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </DataGrid.RowStyle> <!-- 列定义 --> <DataGrid.Columns> <DataGridTextColumn Header="Header" Binding="{Binding MainText}"/> </DataGrid.Columns> <!-- 行详情模板 --> <DataGrid.RowDetailsTemplate> <DataTemplate DataType="{x:Type local:MyViewModel}"> <TextBlock Text="{Binding DetailText}" Padding="20,5"/> </DataTemplate> </DataGrid.RowDetailsTemplate> </DataGrid>
说明:
- 我们重写了
DataGridRow的模板,把行主体和详情拆成两个独立的ContentPresenter - 通过
IsSelected触发器,选中时隐藏主体、显示详情;未选中时恢复默认状态 - 这种方式不需要额外的ViewModel逻辑,适合简单场景
方案2:MVVM模式结合绑定(更易扩展)
如果你的项目遵循MVVM设计模式,建议给ViewModel添加IsSelected属性,通过绑定来控制可见性,这样更灵活:
第一步:修改MyViewModel
using System.ComponentModel; using System.Runtime.CompilerServices; public class MyViewModel : INotifyPropertyChanged { public string MainText { get; set; } public string DetailText { get; set; } private bool _isSelected; public bool IsSelected { get => _isSelected; set { _isSelected = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
第二步:XAML中绑定并控制可见性
<Window.Resources> <!-- 系统内置的布尔转可见性转换器 --> <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> </Window.Resources> <DataGrid ItemsSource="{Binding MyList}" AutoGenerateColumns="False" SelectionUnit="FullRow"> <DataGrid.RowStyle> <Style TargetType="DataGridRow"> <!-- 双向绑定IsSelected到ViewModel --> <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="DataGridRow"> <Grid> <!-- 未选中时显示主体,选中时隐藏 --> <ContentPresenter x:Name="RowMainContent" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=Inverse}"/> <!-- 选中时显示详情,未选中时隐藏 --> <ContentPresenter x:Name="RowDetailsContent" Content="{TemplateBinding DetailsTemplate}" ContentTemplate="{TemplateBinding DetailsTemplate}" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </DataGrid.RowStyle> <DataGrid.Columns> <DataGridTextColumn Header="Header" Binding="{Binding MainText}"/> </DataGrid.Columns> <DataGrid.RowDetailsTemplate> <DataTemplate DataType="{x:Type local:MyViewModel}"> <TextBlock Text="{Binding DetailText}" Padding="20,5"/> </DataTemplate> </DataGrid.RowDetailsTemplate> </DataGrid>
说明:
- 通过双向绑定
DataGridRow.IsSelected到ViewModel的IsSelected属性,把选中状态同步到VM - 利用
BooleanToVisibilityConverter和ConverterParameter=Inverse,轻松控制两个部分的可见性 - 这种方式方便后续扩展逻辑(比如选中时触发其他业务操作)
注意事项
- 不要直接用
DataGridRow.Visibility = Collapsed,因为默认情况下行详情是行的一部分,会跟着行一起隐藏 - 如果需要保留选中行的高亮样式,可以在模板中添加选中状态的背景设置,或者继承默认的DataGridRow模板再修改
内容的提问来源于stack exchange,提问作者user10705768
相关产品推荐
相关产品推荐

