如何隐藏 DataGrid 中的行?

How can I hide rows in a DataGrid?

我正在尝试使用 wpf mvvm 创建一个“笔记”应用程序。我有一个 MainWindow,其中包含一个 DataGrid,其中的数据绑定到一个 ObservableCollection。在 MainWindowView 中,我有一个调用 FindWindowDialog 的“查找”按钮。在文本框中的 FindWindowDialog 中,我必须输入要搜索的文本并单击“查找”,之后 DataGrid MainWindowView 应该隐藏那些内容不包含搜索文本的行。我真的不知道该怎么做,经过 2 天的搜索,我决定问一个问题。我在谷歌上搜索了这个主题,我有一个建议,我应该深入研究信使模式和转换器

MainWindow.xaml(查看)

    <Window x:Class="NotesARK6.View.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:NotesARK6.View"
        xmlns:model="clr-namespace:NotesARK6.Model"
        xmlns:viewmodel="clr-namespace:NotesARK6.ViewModel"
        mc:Ignorable="d"
        Title="Notes" Height="450" Width="800"
        x:Name="_mainWindow"
        WindowStartupLocation="CenterScreen">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="20" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="20" />
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="20"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="10*"/>
            <RowDefinition Height="20"/>
        </Grid.RowDefinitions>

        <DataGrid ItemsSource="{Binding NotesCollection}" SelectedItem="{Binding SelectedNote}" IsReadOnly="True" AutoGenerateColumns="False" x:Name="DataGrid_Notes" Margin="5" Grid.Row="2" Grid.Column="1">
            <DataGrid.InputBindings>
                <MouseBinding Gesture="LeftDoubleClick" Command="{Binding EditNoteCommand}" CommandParameter="{Binding SelectedNote}" />
            </DataGrid.InputBindings>
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Width="1*" Binding="{Binding Name}"/>
                <DataGridTextColumn Header="Content" Width="3*"  Binding="{Binding Content}"/>
            </DataGrid.Columns>
        </DataGrid>
        <ToolBar Grid.Row="1" Grid.Column="1" Margin="5">
            <Button Content="Create" Command="{Binding CreateNewNoteCommand}"/>
            <Separator />
            <Button Content="Delete" Command="{Binding DeleteNoteCommand}" CommandParameter="{Binding SelectedNote}"/>
            <Separator />
            <Button  Content="Find" Command="{Binding FindNoteCommand}"/>
        </ToolBar>
    </Grid>
</Window>

FindWindowDialog.xaml(查看)

    <Window x:Class="NotesARK6.ViewModel.Dialogs.FindWindowDialog"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:NotesARK6.ViewModel.Dialogs"
        mc:Ignorable="d"
        Title="Find" Height="250" Width="400"
        WindowStartupLocation="CenterScreen"
        Topmost="True">
        
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="20"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="20"/>
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="40"/>
            <RowDefinition Height="35"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="90"/>
        </Grid.RowDefinitions>

        <Grid Grid.Row="1" Grid.Column="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>

            <CheckBox  IsChecked="{Binding SearchByName}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5" Content="Search by name" Grid.Column="0"></CheckBox>
            <CheckBox IsChecked="{Binding SearchByContent}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5" Content="Search by content" Grid.Column="1"></CheckBox>
        </Grid>
        
        <TextBox Text="{Binding SearchString}" Margin="5" Grid.Row="2" Grid.Column="1"/>
        <Button Command="{Binding FindNotesCommand}" Margin="5" Content="Find" Grid.Row="3" Grid.Column="1" /> 
    </Grid>
</Window>

FindWindowDialogViewModel.cs

public class FindWindowDialogViewModel : INotifyPropertyChanged
{
    private string searchString;
    private bool searchByName;
    private bool searchByContent;

    //Controll Commands
    public ControllComands FindNotesCommand { get; private set; }
    //Controll Commands 

    public FindWindowDialogViewModel()
    {
        FindNotesCommand = new ControllComands(FindNote);
    }

    public string SearchString 
    {
        get
        {
            return searchString;
        }
        set
        {
            searchString = value;
            OnPropertyChanged();
        }
    }

    public bool SearchByName
    {
        get
        {
            return searchByName;
        }
        set
        {
            searchByName = value;
            OnPropertyChanged("SearchByName");
        }
    }

    public bool SearchByContent
    {
        get
        {
            return searchByContent;
        }
        set
        {
            searchByContent = value;
            OnPropertyChanged("SearchByContent");
        }
    }

    public void FindNote()
    {
        MessageBox.Show(SearchByName.ToString() + " " + SearchByContent.ToString());
    }


    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName]string prop = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
}

如何使用 FindWindowDialogViewModel 中包含的命令隐藏 DataGrid MainWindowView 中的行?

我想要这样的东西:(这是伪代码)

public void FindNote()
    {
        foreach(var row in MainWindow.DataGrid.Rows)
        {
            string searchingText = FindNoteDialog.TextBox.Text;

            if (!row.Content.Contains(searchingText))
            {
                row.Visibillity = false;
            }
        }
    }

为此,集合通过其视图提供过滤功能(请参阅 Binding to collections and CollectionView API 备注以了解更多信息)。
使用集合的视图进行过滤比隐藏行或从原始集合中删除项目具有更好的性能。

为此,您必须获取源集合

ICollectionView

Note.cs

class Note
{
  public string Summary { get; set; }
  public DateTime Timestamp { get; set; }
}

ViewModel.cs

class ViewModel : INotifyPropertyChanged
{
  public ObservableCollection<Note> Notes { get; }
  public string SearchKey { get; set; }
  public ICommand FilterNotesCommand => new RelayCommand(ExecuteFilterNotes);

  private void ExecuteFilterCommands(object commandParameter)
  {
    ICollectionView notesView = CollectionViewSource.GetDefaultView(this.Notes);
    notesView.Filter = item => (item as Note).Summary.Contains(this.SearchKey);
  }
}

MainWindow.xaml

<Window>
  <Window.DataContext>
    <ViewModel />
  </Window.DataContext>

  <StackPanel> 
    <TextBox Text="{Binding SearchKey}" />
    <Button Command="{Binding FilterNotesCommand}" Content="Filter Table" />
    <DataGrid ItemsSource="{Binding Notes}" />
  </StackPanel>
</Window>