WPF скрыть строку в datagrid на основе условия

Мне нужно скрыть строки в datagrid на основе параметров и значений в datagrid. Я решил сделать что-то подобное:

foreach (System.Data.DataRowView dr in myDataGrid.ItemsSource)
{
   //Logic to determine if Row should be hidden
   if (hideRow == "Yes")
   {
      //Hide row code
   }
}

Я просто не могу понять, как скрыть строку. Обратите внимание, что я не хочу удалять строку с помощью datagrid или источника элемента.

Ответ 1

Если hideRow не является полем таблицы (т.е. не является столбцом в DataGridRow):

<DataGrid.RowStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding AnyProp, Converter={StaticResource hiddenConverter}}" Value="True">
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</DataGrid.RowStyle>

И воплотите Конвертер с вашей логикой. Тип связанной переменной AnyProp, приведенной выше, будет ниже вашего типаPropertyType. AnyProp может быть любым из столбцов в строке.

[ValueConversion(typeof(yourPropType), typeof(bool))]
public class hiddenConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (hideRow == "Yes")
        {
           return true;
        }
        else
        {
           return false;
        }
    }


}

'value' будет AnyProp, и его можно использовать в логике, которая определяет, показывать или не показывать строку, или это решение может быть основано на чем-то совсем другом, например "hideRow" в этом примере.

Ответ 2

Вы можете сделать это в Datagrid.ItemContainerStyle вместо того, чтобы делать это в codebehind...

  <DataGrid>
      <DataGrid.ItemContainerStyle>
            <Style TargetType="DataGridRow">
                 <Style.Triggers>
                       <DataTrigger Binding="{Binding PROPERTY}"  Value="VALUE">
                              <Setter Property="Visibility" Value="Collapsed"/>

Ответ 3

Используйте CollectionViewSource, чтобы связать DataGrid с вашими бизнес-данными. CollectionViewSource запускает событие фильтра для каждой строки. В этом случае ваш код может решить, должна ли отображаться строка.

Добавьте в свой XAML:

<Window.Resources>
  <CollectionViewSource x:Key="sampleViewSource" CollectionViewType="ListCollectionView"/>
</Window.Resources>

<DataGrid DataContext="{StaticResource sampleViewSource}" ItemsSource="{Binding}"
            AutoGenerateColumns="False">

Добавьте в свой код за файлом следующее:

stocksViewSource = ((System.Windows.Data.CollectionViewSource)(FindResource("sampleViewSource")));
sampleViewSource.Filter += sampleViewSource_Filter;

Создайте обработчик событий фильтра. Вы можете получить данные строки из e.Item. Установив e.Accepted, вы можете контролировать, должна ли строка отображаться.

Ответ 4

<Window x:Class="ProjectName.ClassName"
        xmlns:C="clr-namespace:ProjectName.FolderName"> //Folder containing 'VisibilitySetter' class.
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

  <Window.Resources>
    <C:VisibilitySetter x:Key="VisibilitySetter" />
  </Window.Resources>

  <DataGrid ItemsSource="{Binding SomeObservableCollectionProperty}">
    <DataGrid.RowStyle>
      <Style TargetType="DataGridRow">
        <Setter Property="Visibility" Value="{Binding Path=., Converter={StaticResource VisibilitySetter}, ConverterParameter=1}" />
      </Style>
    </DataGrid.RowStyle>

    </DataGridTextColumn>
      <DataGridTextColumn Binding="{Binding PropertyName1}" />
      <DataGridTextColumn Binding="{Binding PropertyName2}" />
      //................
  </DataGrid>
</Window >

VisibilitySetter - это класс, который реализует IValueConverter. Вот класс...

public class VisibilitySetter:IValueConverter 
{
  public object Convert(object value,Type targetType,object parameter,CultureInfo culture)
  {
    if(parameter.ToString() == "1")  //Parameter is set in the xaml file.
    {
      return SetVisibilityBasedOn(value);
    }
    return null;
  }

  private object SetVisibilityBasedOn(object value)
  {
    if(value is SomeObject obj && obj.value == "SomeValue") //Checks the value of the object
    {        
      return Visibility.Collapsed;  //Hides the row. It Returns visibility based on the value of the row.
    }
    return null;
  }
}