WPF DataGrid Hide RowDetails или Unselect Row

У меня есть 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%, но после того, как данные строки свернуты для данной строки, он не появится в следующий раз, когда будет выбрана строка.

Ответ 1

Я тоже столкнулся с этим. Здесь решение:

Сохраните эту кнопку в RowDetails и немного измените ее код. Вместо того, чтобы сосредоточиться на видимости отдельных строк, установите для свойства DataGrid SelectedIndex значение -1 (ни один не выбран).

DataGrid1.SelectedIndex = -1;

Поскольку ваш RowDetailsVisibilityMode равен VisibleWhenSelected, DataGrid будет свернуть/скрыть все расширенные RowDetails. Это хорошо работает, когда SelectionMode Single.

Ответ 2

Вы можете реализовать это со следующим кодом в 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.

В коде С# вы сделаете следующее:

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;
            }
        }                
    }

Это очень сработало для меня.

Ответ 3

вы можете поместить это как событие нажатия кнопок, оно подбирается к дереву, находит datarow и задает детали там, где это необходимо.

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;
            }
        }

Ответ 4

попробуйте добавить row.DetailsVisibility = Visibility.Visible; в событие RowDetailsVisibilityChanged.

Ответ 5

Попробуйте установить стиль на кнопке с сеттерами, которые задают свойства Button 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 для других ваших DataGrids, а также уменьшить обработку событий.

Вы можете увидеть рабочий пример в этот проект Silverlight-to-WPF DataGrid с открытым исходным кодом.

Ответ 6

Попробуйте это (добавив событие PreviewMouseDown в DataGrid в XAML):

 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;
                }
            }
        }
    }

Ответ 7

Убедитесь, что у вашего datagrid есть имя, например

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

Поместите кнопку в шаблон строки, например

<DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <Button Content="X" Click="Button_Click" Width="20"/>
         ....

Затем в коде просто установите для выделенного индекса datagrid значение -1

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