WPF数据网格 隐藏行详细信息 或 取消选择行

12

我有一个DataGrid,它的RowDetails设置为在选择时显示(RowDetailsVisibilityMode="VisibleWhenSelected")。现在我想要能够摆脱它!我在行细节上放置了一个关闭按钮,并使用此代码:

private void Button_Click(object sender, RoutedEventArgs e)
  {
   e.Handled = true;
   Button button = sender as Button;
   DataGridRow row = button.FindAncestor<DataGridRow>();

   row.DetailsVisibility = Visibility.Collapsed;
  }

这段代码让我完成了90%的工作,但是一旦某一行的详细信息被折叠,下次选中该行时就不会再出现。

7个回答

13

我也遇到过这个问题。这是解决方案:

将按钮保留在RowDetails中,并对其代码进行一些更改。不要关注单个行的可见性,而是将DataGrid的SelectedIndex属性设置为-1(没有选定任何项)。

DataGrid1.SelectedIndex = -1;

由于您的RowDetailsVisibilityMode是VisibleWhenSelected,所以DataGrid将折叠/隐藏任何已展开的RowDetails。当SelectionMode为Single时,这很有效。


8
您可以在XAML中使用以下代码实现此功能:
<WpfToolkit:DataGrid Name="dgSysthetic" ItemsSource="{Binding}" 
    AutoGenerateColumns="True"      
    SelectionMode="Extended"
    RowDetailsVisibilityMode="Collapsed"
    CanUserAddRows="False" CanUserDeleteRows="False"
    CanUserResizeRows="False" CanUserSortColumns="False"
    RowHeaderWidth="20" RowHeight="25">
    <WpfToolkit:DataGrid.RowHeaderTemplate>
        <DataTemplate>
            <Button Name="btnHideRow" Click="btnHideDetails_Click" FontSize="5">></Button>
        </DataTemplate>
    </WpfToolkit:DataGrid.RowHeaderTemplate>
    <WpfToolkit:DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <WpfToolkit:DataGrid Name="dgAnalytical" ItemsSource="{Binding}" AutoGenerateColumns="True"/>                 
        </DataTemplate>
    </WpfToolkit:DataGrid.RowDetailsTemplate>        
</WpfToolkit:DataGrid>

请查看RowHeaderTemplate内部的按钮。

在C#代码中,您可以这样做:

private void btnHideDetails_Click(object sender, RoutedEventArgs e) 
    { 
        DependencyObject obj = (DependencyObject)e.OriginalSource; 
        while (!(obj is DataGridRow) && obj != null) obj = VisualTreeHelper.GetParent(obj);

        if (obj is DataGridRow)
        {
            if ((obj as DataGridRow).DetailsVisibility == Visibility.Visible)
            {
                (obj as DataGridRow).DetailsVisibility = Visibility.Collapsed;
            }
            else
            {
                (obj as DataGridRow).DetailsVisibility = Visibility.Visible;
            }
        }                
    }

这对我非常有效。

1
尽管这可能是合法的代码,但它使用了可能与OP的问题不兼容的WpfToolkit。 - user585968

3
你可以把这段代码放在按钮的click事件中,它会向上查找树形结构中的数据行,并设置相应的细节信息。
DependencyObject dep = (DependencyObject)e.OriginalSource;
        while ((dep != null) && !(dep is DataGridRow))
        {
            dep = VisualTreeHelper.GetParent(dep);
        }
        if (dep != null && dep is DataGridRow)
        {
            DataGridRow row = dep as DataGridRow;
            if (row.DetailsVisibility == Visibility.Collapsed)
            {
                row.DetailsVisibility = Visibility.Visible;
            }
            else
            {
                row.DetailsVisibility = Visibility.Collapsed;
            }
        }

1
尝试使用Setters在按钮上设置样式,设置按钮的Command和CommandParameter属性。您需要创建一个实现ICommand接口的类,并将其作为StaticResource包含在XAML中。这里我将DataGridRowHeader用作按钮,而不是在行详细信息中使用按钮。
     <local:DeselectRowCommand x:Key='deselectCommand' />
            <Setter Property='Command' Value='{StaticResource deselectCommand}' />
                <Setter Property='CommandParameter' 
    Value='{Binding RelativeSource={RelativeSource Mode=FindAncestor, 
AncestorType=wpf:DataGridRow}}' />

在命令的Execute方法中,您可以从命令参数获取DataGridRow并应用任何您需要的方法。

至少这样,您可以共享此样式或以此为基础创建其他样式,并重复使用ICommand以用于其他DataGrid,同时减少事件处理。

您可以在此开源项目Silverlight-to-WPF DataGrid中查看一个实际的示例。


1
尝试在RowDetailsVisibilityChanged事件中添加row.DetailsVisibility = Visibility.Visible;

0

确保你的数据网格有一个名称,例如

<DataGrid x:Name="dgPrimary"
          ...> 

在行模板中放置一个按钮,例如:
<DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <Button Content="X" Click="Button_Click" Width="20"/>
         ....

然后在代码后端将数据表格的选中索引设置为-1即可。

private void Button_Click(object sender, RoutedEventArgs e)
{
    dgPrimary.SelectedIndex = -1;
}

0
尝试这个(在XAML中将PreviewMouseDown事件添加到您的DataGrid中):
 private void UIElement_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        DataGrid grid = sender as DataGrid;

        if (grid != null)
        {
            FrameworkElement element = e.OriginalSource as FrameworkElement;

            if (element?.DataContext is FixedIncomeOrder)
            {
                if (grid.SelectedItem == (FixedIncomeOrder) ((FrameworkElement) e.OriginalSource).DataContext)
                {
                    grid.SelectedIndex = -1;
                    e.Handled = true;
                }
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接