Вопрос по c#, wpf – как обрабатывать промежуточные итоги группы и, например, целевые строки в WPF DataGrid?

12

Я реализую WPF DataGrid, которая содержит проекты со многими показателями. Проекты сгруппированы по категориям проектов.

Для каждой категории должно быть:

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

Эти строки должны быть всегда наверху в каждой группе (фильтрация сортировки).

Моим первым решением было поместить эти данные в заголовок группы. Это не хорошее решение, потому что заголовок группы не поддерживает столбцы. то есть это должно быть построено, получая ширину столбца.

Это можно сделать, но это усложняется, когда пользователи хотят изменить порядок и скрыть столбцы.

DataGrid использует CollectionViewSource, поэтому он не заполнен кодом C #. В основном я расширяю этот пример:http: //msdn.microsoft.com/en-us/library/ff407126.asp

Спасибо и С наилучшими пожеланиями - Матти

Ты нашел способ ответить на этот вопрос? Вот мой ТАК вопрос (который я пометил как дубликат): / Stackoverflow.com вопросы / 46206673 / ... Simon

Ваш Ответ

2   ответа
0

чтобы добавить строки в источнике данных со специальными значениями для имени и других полей, которые не имеют смысла, и использовать 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:

2

ом из моих проектов. Мы не были обеспокоены некоторыми проблемами, которые вы затронули, такими как скрытие и сортировка столбцов, поэтому я не знаю точно, можно ли их расширить для этого. Я также понимаю, что могут быть проблемы с производительностью, которые могут быть проблемы с большими наборами (мое окно работает 32 отдельных DataGrids - ой). Но это направление отличается от других решений, которые я видел, поэтому я подумал, что я добавлю его сюда и посмотрю, поможет ли оно вам.

Мое решение состоит из 2 основных компонентов:
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 и с помощью специальной команды Copy оказалось довольно прост

Мне жаль, что я не проверяю твой ответ. я надеюсь, что это помогает другим людям. char m

Похожие вопросы