Самый простой способ переключения между 1 и 0 состоит в вычитании из 1.
def toggle(value):
return 1 - value
Один из вариантов может состоять в том, чтобы добавить строки в источник данных со специальными значениями для имени и других полей, которые не имеют смысла, и использовать DataTrigger для отображения их со специальными цветами и, возможно, с некоторыми другими.
Фильтрация выполняется в C # в любом случае, поэтому она не влияет на эти строки.
Сортировка - единственная проблема здесь. Было бы здорово просто сказать, что некоторые строки всегда имеют порядок 0 и с порядком 1 в группе. Но я не знаю, как это сделать. Мне нужно сделать обычную сортировку на C # для всех столбцов, а не просто объявлять сортировку:
<CollectionViewSource.SortDescriptions>
<!-- Requires 'xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"' declaration. -->
<scm:SortDescription PropertyName="ProjectName"/>
<scm:SortDescription PropertyName="Complete" />
<scm:SortDescription PropertyName="DueDate" />
</CollectionViewSource.SortDescriptions>
EDIT: Вдобавок ко всему остальное это имеет главный недостаток, сравнимый с мое первое решение (информация о сумме в заголовке группы), потому что при фильтрации изменений я должен обновлять суммы, которые будут вычисляться только для видимых строк.
Таким образом, этот ответ является полным взломом и не обладает всей элегантностью и не использует ничего хорошего функции, которые WPF должен иметь: (
У меня есть обработанный DataGrid с группами промежуточных строк в одном из моих проектов. Мы не беспокоились о некоторых проблемах, которые вы вызываете, например о скрытии и сортировке столбцов, поэтому я точно не знаю, может ли он быть расширен для этого. Я также понимаю, что могут быть проблемы с производительностью, которые могут быть проблемой при работе с большими наборами (мое окно работает с 32 отдельными DataGrids - ouch). Но это другое направление от других решений, которые я видел, поэтому я подумал, что брошу его сюда и посмотрю, поможет ли он вам.
Мое решение состоит из двух основных компонентов: 1. Подзаголовок строки не являются строками в основном DataGrid, а являются отдельными DataGrids. У меня есть 2 дополнительных сетки в каждой группе: 1 в заголовке, который отображается только тогда, когда группа рухнула, а другая - под пунктом ItemsPresenter. Элемент ItemsSource для промежуточных DataGrids поступает из конвертера, который берет элементы в группе и возвращает общую модель представления. Столбцы промежуточных сеток точно такие же, как и основная сетка (заполнены в DataGrid_Loaded, хотя я уверен, что это можно сделать и в xaml тоже).
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander Background="Gray" HorizontalAlignment="Left" IsExpanded="True"
ScrollViewer.CanContentScroll="True">
<Expander.Header>
<DataGrid Name="HeaderGrid" ItemsSource="{Binding Path=., Converter={StaticResource SumConverter}}"
Loaded="DataGrid_Loaded" HeadersVisibility="Row"
Margin="25 0 0 0" PreviewMouseDown="HeaderGrid_PreviewMouseDown">
<DataGrid.Style>
<Style TargetType="DataGrid">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander}, Path=IsExpanded}"
Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Style>
</DataGrid>
</Expander.Header>
<StackPanel>
<ItemsPresenter/>
<DataGrid Name="FooterGrid" ItemsSource="{Binding ElementName=HeaderGrid, Path=ItemsSource, Mode=OneWay}"
Loaded="DataGrid_Loaded" HeadersVisibility="Row"
Margin="50 0 0 0">
<DataGrid.Style>
<Style TargetType="DataGrid">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Expander}, Path=IsExpanded}"
Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid>
</StackPanel>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
2. Тогда проблема как заставить все DataGrids вести себя так, как если бы они были единой сеткой. Я обработал это путем подкласса DataGridTextColumn
(у нас есть только текст в этом случае, но другие типы столбцов тоже должны работать) в классе с именем DataGridSharedSizeTextColumn
, который имитирует поведение SharedSizeGroup класса Grid. Он имеет свойство строковой зависимости с именем группы и отслеживает все столбцы в одной группе. Когда Width.DesiredValue
изменяется в одном столбце, я обновляю MinWidth во всех остальных столбцах и принудительно обновляю с помощью DataGridOwner.UpdateLayout()
. Этот класс также охватывает переупорядочение столбцов и обновляет группу, всякий раз, когда изменяется DisplayIndex. Я бы подумал, что этот метод также будет работать с любым другим свойством столбца, если у него есть сеттер.
Были другие неприятные вещи, которые нужно было решать с выбором, копированием и т. Д. Но это оказалось довольно легко обрабатывается событиями MouseEntered и MouseLeave и с помощью специальной команды копирования.