C# 使用MVVM模式在WPF数据网格中显示/隐藏行功能

C# 使用MVVM模式在WPF数据网格中显示/隐藏行功能,c#,wpf,xaml,datagrid,C#,Wpf,Xaml,Datagrid,我试图实现一个简单的隐藏/显示行功能 用户会看到一个带有行的数据网格,在左侧有一个按钮“Hide”,它隐藏了给定的行。 还有一个按钮“显示隐藏行”,它将显示所有行,以及隐藏的行。隐藏的行,应该在左边的“ShowRow”上有一个按钮,将其带回主数据网格。之后,用户可以再次按“隐藏隐藏行” 所有行都是自动生成的 我的做法: 数据网格的源是: private DataView _dataView; public DataView DataView {

我试图实现一个简单的隐藏/显示行功能

用户会看到一个带有行的数据网格,在左侧有一个按钮“Hide”,它隐藏了给定的行。 还有一个按钮“显示隐藏行”,它将显示所有行,以及隐藏的行。隐藏的行,应该在左边的“ShowRow”上有一个按钮,将其带回主数据网格。之后,用户可以再次按“隐藏隐藏行”

所有行都是自动生成的

我的做法:

数据网格的源是:

 private DataView _dataView;

        public DataView DataView
        {
            get { return _dataView; }
            set
            {
                _dataView = value;
                RaisePropertyChanged("DataView");
            }
        }
XAML添加了一个“隐藏”按钮:

这种修改实际数据视图的方法的问题是,一旦用户按下“显示隐藏行”,我希望能够显示所有行。我可以创建几个数据视图,这些数据视图将保存隐藏行、当前行和要返回的行。这似乎不是直觉

  • 基于的DataGridRow的可见性属性
  • 
    
    如果我将rowVisibility设置为“Collapsed”,它将折叠所有行,我无法仅隐藏某一行

  • 我也知道,但这并不取决于行数据本身,而是取决于用户。我也研究过,但似乎这些依赖于被操纵的数据视图。我还研究了一个复选框,它将使用可见性转换器隐藏某一行,但同样,它不允许我管理隐藏行

  • 我正试图找到一种方法来隐藏x数量的行,并能够管理它们。我希望能够使它们再次出现,标记为隐藏,以便用户可以使它们再次可见

    正确的方法是使用
    按钮注册事件处理程序。单击
    事件。此行为是视图逻辑,不属于视图模型。视图模型不执行与视图相关的逻辑。它总是执行与模型相关的逻辑

    另一种解决方案是实现附加的行为,这是一个带有行为的附加属性

    main window.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>
    
    HelperExtensions.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;
        }
      }
    }
    
    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;
      }
    }
    
    公共静态类HelperExtensions
    {
    public static bool TryFindVisualParentElement(此DependencyObject子对象,out tParentResultElement)
    其中TParent:DependencyObject
    {
    resultElement=null;
    DependencyObject parentElement=VisualTreeHelper.GetParent(子级);
    if(parentElement是TParent父元素)
    {
    结果成分=父母;
    返回true;
    }
    返回parentElement?.TryFindVisualParentElement(OutResultElement)?false;
    }
    }
    
    这看起来是一个了不起的解决方案!我唯一的问题是函数“ShowAllRows”显示所有行,而不标记以前隐藏的行!其思想是,用户可以在隐藏后选择几行返回可见性。
    <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>
    
    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;
        }
      }
    }
    
    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;
      }
    }