Показать / скрыть функциональность строк в WPF DataGrid с использованием шаблона MVVM - PullRequest
0 голосов
/ 06 февраля 2020

Я пытаюсь реализовать простую функцию скрытия / отображения строк.

Пользователю показывается DataGrid со строками, с левой стороны есть кнопка «Скрыть», которая скрывает данную строку. Также есть кнопка «Показать скрытые строки», которая должна показать все строки, в том числе и скрытые. Скрытые строки, должны иметь кнопку слева «Показать строку», чтобы вернуть ее в основную DataGrid. После этого пользователь может снова нажать «скрыть скрытые строки».

Все строки генерируются автоматически.

Мой подход:

Источник DataGrid:

 private DataView _dataView;

        public DataView DataView
        {
            get { return _dataView; }
            set
            {
                _dataView = value;
                RaisePropertyChanged("DataView");
            }
        }

В XAML добавлена ​​кнопка «Скрыть» :

<DataGrid.Columns>
                <DataGridTemplateColumn Header="Hide Row">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button Content="{Binding Path=DataContext.HideRowButtonText, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"  CommandParameter="{Binding Path=SelectedIndex, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Command="{Binding Path=DataContext.HideRowCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
</DataGrid.Columns>

Мои попытки:

  1. Управление DataView
private void HideRow(object obj)
        {
            DataView.Table.Rows.RemoveAt(Convert.ToInt32(obj));
        }

Проблема с этим подходом, который модифицирует фактическое DataView, заключается в что я хочу иметь возможность показывать все строки, когда пользователь нажимает «Показать скрытые строки». Я мог бы создать несколько DataView, которые будут содержать скрытые строки, текущие строки и строки, которые возвращаются. Это кажется не интуитивным.

Свойство видимости в DataGridRow на основе this.
<DataGrid.RowStyle>
                <Style TargetType="DataGridRow">
                    <Setter Property="Visibility" Value="{Binding Path=DataContext.RowVisibility, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" />
                </Style>
</DataGrid.RowStyle>

Если для RowVisibilty установить значение "Свернуто", оно свернет все строки, я не смог скрыть только определенную строку.

Я также знаю о DataTriggers , но это зависит не от самих данных строки, а от пользователя. Я также изучил Фильтры строк , но, похоже, они зависят от манипулирования DataView. Я также изучил наличие CheckBox, который будет скрывать определенную строку с помощью конвертера видимости, но опять же, не позволяя мне управлять скрытыми строками.

Я пытаюсь найти способ скрыть х количество строк, и сможете управлять ими. Я хочу, чтобы они снова отображались, помечались как скрытые, чтобы пользователь мог снова сделать их видимыми!

1 Ответ

0 голосов
/ 06 февраля 2020

Правильный подход заключается в регистрации обработчиков событий с событием Button.Click. Такое поведение является логикой представления c и не относится к модели представления. Модель представления не выполняет логики, связанные с представлением c. Он всегда выполняет связанные с моделью логи c.

Альтернативным решением будет реализация присоединенного поведения, которое является присоединенным свойством с поведением.

MainWindow.xaml

<StackPanel>
  <Button Content="Show All Hidden Rows"  
          Click="ShowAllRows_OnButtonClicked" />

  <DataGrid x:Name="MyDataGrid">
    <DataGrid.Columns>
      <DataGridTemplateColumn Header="Hide Row">
        <DataGridTemplateColumn.CellTemplate>
          <DataTemplate>
            <Button Content="Hide Row"
                    Click="HideRow_OnButtonClicked" />
          </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
      </DataGridTemplateColumn>
    </DataGrid.Columns>    
  </DataGrid>
</StackPanel>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
  private void HideRow_OnButtonClicked(object sender, RoutedEventArgs e)
  {
    // Use the extension method to traverse the visual tree to search for the parent row
    if ((sender as DependencyObject).TryFindVisualParentElement(out DataGridRow dataGridRow))
    {
      dataGridRow.Visibility = Visibility.Collapsed;
    }
  }

  private void ShowAllRows_OnButtonClicked(object sender, RoutedEventArgs e)
  {
    foreach (object rowData in this.MyDataGrid.Items)
    {
      (this.MyDataGrid.ItemContainerGenerator.ContainerFromItem(rowData) as FrameworkElement).Visibility =
        Visibility.Visible;
    }
  }
}

HelperExtensions.cs

public static class HelperExtensions
{
  public static bool TryFindVisualParentElement<TParent>(this DependencyObject child, out TParent resultElement)
    where TParent : DependencyObject
  {
    resultElement = null;

    DependencyObject parentElement = VisualTreeHelper.GetParent(child);

    if (parentElement is TParent parent)
    {
      resultElement = parent;
      return true;
    }

    return parentElement?.TryFindVisualParentElement(out resultElement) ?? false;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...